Haeri
Haeri
CC#
Created by Haeri on 1/18/2024 in #help
EF Core Nested Projections
No description
10 replies
CC#
Created by Haeri on 1/18/2024 in #help
EF Core Nested Projections
@Joschi As far as I can see the mapper just auto generates mappings https://mapperly.riok.app/docs/getting-started/generated-mapper-example/#the-generated-code But I don't think I can directly use it in the projection. The next best thing I found was this: https://mapperly.riok.app/docs/configuration/queryable-projections/ But I will run into the same issue there because I would have to do something like this:
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public UserDTO User { get; set; }
}

public static class BlogMapper
{
public static IQueryable<BlogDTO> ProjectToDto(this IQueryable<Blog> query)
{
return query.Select(authUser => new BlogDTO()
{
Id = blog.Id,
Title = blog.Title,
User = new UserDTO() // I have to again manually map User
{
Id = blog.User.Id
UserName = blog.User.UserName
}
});
}
}
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public UserDTO User { get; set; }
}

public static class BlogMapper
{
public static IQueryable<BlogDTO> ProjectToDto(this IQueryable<Blog> query)
{
return query.Select(authUser => new BlogDTO()
{
Id = blog.Id,
Title = blog.Title,
User = new UserDTO() // I have to again manually map User
{
Id = blog.User.Id
UserName = blog.User.UserName
}
});
}
}
10 replies
CC#
Created by Haeri on 1/18/2024 in #help
EF Core Nested Projections
For example I have a lot more Models that have a relationship with User so I need to write the same code multiple times for every relationship
10 replies
CC#
Created by Haeri on 1/18/2024 in #help
EF Core Nested Projections
I found two suggestions: Explicit Operator
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public UserDTO User { get; set; }

public static explicit operator BlogDTO(Blog blog) => new()
{
Id = blog.Id,
Title = blog.Title,
User = (UserDTO)blog.User
};
}

/* same for User -> UserDTO */

var result = dbContext.Blogs
.Select(e => (BlogDTO)e)
.toList();
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public UserDTO User { get; set; }

public static explicit operator BlogDTO(Blog blog) => new()
{
Id = blog.Id,
Title = blog.Title,
User = (UserDTO)blog.User
};
}

/* same for User -> UserDTO */

var result = dbContext.Blogs
.Select(e => (BlogDTO)e)
.toList();
This makes life a lot easier but unfortunately I found out that the SQL generated by this does not use projection but always gets the all properties. Expression Functions
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public UserDTO User { get; set; }

public static Expression<Func<Blog, BlogDTO>> BlogToDTO()
{
return blog=> new BlogDTO
{
Id = blog.Id,
Title = blog.Title,
User = UserToDto().Compile()(blog.User)
};
}
}

/* same for User -> UserDTO */

var result = dbContext.Blogs
.Select(BlogDTO.BlogToDTO())
.toList();
public class BlogDTO
{
public int Id { get; set; }
public string Title { get; set; }
public UserDTO User { get; set; }

public static Expression<Func<Blog, BlogDTO>> BlogToDTO()
{
return blog=> new BlogDTO
{
Id = blog.Id,
Title = blog.Title,
User = UserToDto().Compile()(blog.User)
};
}
}

/* same for User -> UserDTO */

var result = dbContext.Blogs
.Select(BlogDTO.BlogToDTO())
.toList();
But this gives me the following error:
The client projection contains a reference to a constant expression of 'System.Func<User, UserDTO>'. This could potentially cause a memory leak; consider assigning this constant to a local variable and using the variable in the query instead.
The client projection contains a reference to a constant expression of 'System.Func<User, UserDTO>'. This could potentially cause a memory leak; consider assigning this constant to a local variable and using the variable in the query instead.
10 replies