我使用Entity Framework Core 2.0并拥有这两个类:
新闻
public class News
{
public int Id { get; set; }
public string Title{ get; set; }
public string Text { get; set; }
public DateTime ReleaseDate{ get; set; }
public int AuthorID{ get; set; }
public Author Author{ get; set; }
}
作者
public class Author
{
public Author ()
{
News = new List<News>();
}
public int Id { get; set; }
public string Username{ get; set; }
public string Firstname{ get; set; }
public string Lastname{ get; set; }
public ICollection<News> News {get;set;}
}
我想用作者的用户名加载新闻,因为我不需要其他信息,如作者的名字和姓氏。
如果我执行此操作:
static void Main(string[] args)
{
using (var ctx = new DbContext())
{
var result= ctx.News.Include(x => x.Author).Select(news => new
{
news= news ,
Username= pr.Author.Username
}).ToList();
}
}
Entity Framework Core 2.0生成一个数据库查询,如:
SELECT [x].[ID], [x].[Text], [x].[Title], [x].[AuthorId], [x].[ReleaseDate], [x.Author].[ID], [x.Verfasser].[Username] AS [Username], [x.Verfasser].[Firstname], [x.Verfasser].[Lastname]
FROM [News] AS [x]
INNER JOIN [Author] AS [x.Author] ON [x].[AuthorId] = [x.Author].[ID]
有没有办法达到我预期的行为?
答案 0 :(得分:12)
如果我理解正确,您不想加载Author
实体(因为无法加载实体,只填充了一些非导航属性)。
然后问题是你为什么要专门添加请求EF加载Include(x => x.Author)
的{{1}}。 Author
/ Include
方法支持热切加载相关数据实体。使用投影(ThenInclude
)时不需要它们。
有趣的是,EFC 2.0之前的所有EF(Core)版本都忽略了投影类型查询的包含。即使是当前的EFC文档也表明投影查询属于Ignored Includes类别。但是,正如您已经注意到EFC 2.0并没有忽略它!所以它是实现错误,将被修复,或文档错误,并将更新。
目前,只是不要在投影查询中使用Select
。如果你执行这个:
Include
现在,EFC生成的SQL查询符合预期:
var result = ctx.News.Select(news => new
{
news = news,
Username = news.Author.Username
}).ToList();
答案 1 :(得分:1)
您可以从基础层返回方法IQueryable<News> GetAll()
,而不必使用匿名对象,而只需执行context.NewsTable.Include(x => x.Author)
。
Obs:请注意,此时您只是返回查询,并且不从数据库中检索数据。
然后,使用您要检索的属性(例如下面的示例)创建一个NewsDTO
类。
public class NewsDTO
{
public int Id { get; set; }
public string Title{ get; set; }
public string Text { get; set; }
public DateTime ReleaseDate{ get; set; }
public string AuthorName { get; set; }
}
我更喜欢使用AutoMapper,您的代码会更简洁List<NewsDTO> newsDtoList = _repository.GetAll().ProjectTo<NewsDTO>().ToList()
但是您可以使用这种奇怪的类型
List<NewsDTO> newsDtoList = _repository.GetAll()
.Select(x => new NewsDTO
{
Id = x.Id.,
Title = x.Title,
Text = x.Text,
ReleaseDate = x.ReleaseDate,
AuthorName = x.Author.Username
}).ToList();
您可以使用.ToList()
完成命令,此时您将检索数据,只需选择一个,即可在映射配置或选择中定义字段。