我有这三个模型A,B,C。
假设这些类看起来像:
Public class A
{
public int Id {get;set;}
public string Name {get;set;}
public ICollection<B> bc {get;set;}
public ICollection<C> cc {get;set}
}
Public class B
{
public int Id {get;set;}
public string Name {get;set;}
}
Public class C
{
public int Id {get;set;}
public string Name {get;set;}
}
假设我要从A中除cc或bc之外的所有数据。
问题是,每当我调用getall方法时,它都会返回所有相关的内容,实际上,它在我的代码中要复杂得多,因此B和C中也存在集合,这些集合带来了几乎所有的东西,并且执行需要花费大量时间,就像一个循环。
到目前为止,我已经尝试过使用select,但是仍然可以进入模型并获取所有字段。
任何帮助,请谢谢。
答案 0 :(得分:0)
您可以使用数据注释从模型中排除属性。您可以访问以下链接:https://docs.microsoft.com/en-us/ef/core/modeling/included-properties以获取更多信息。希望对大家有帮助,新年快乐,我的朋友:))
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[NotMapped]
public DateTime LoadedFromDatabase { get; set; }
}
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Ignore(b => b.LoadedFromDatabase);
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public DateTime LoadedFromDatabase { get; set; }
}
答案 1 :(得分:0)
我怀疑您可能没有正确使用.Select
,因为这正是它的设计目的。
要获取相关的A细节(不包含B或C):
var aDetails = context.As.Select(a => new { a.Id, a.Name }).ToList();
请注意,这将返回一个匿名类型,该类型仅包含您想要的字段,在这种情况下,是A记录中的ID和名称。现在,如果您想返回要在视图等中使用的数据,则可以定义一个名为AViewModel的视图模型类,例如,具有该ID和名称:
var viewModels = context.As.Select(a => new AViewModel{ Id = a.Id, Name = a.Name }).ToList();
人们常常试图将实体发送到视图而陷入困境。这是一种糟糕的模式,为了避免定义另一个看起来很像该实体的POCO类,经常会给它上上光。但是,有两个非常好的理由应该避免:信息的安全性和性能。 (概述here)如果您执行以下操作:
var results = context.As.ToList();
甚至
var results = context.As.Select(a => a).ToList();
启用了LazyLoading(EF6),这将仅加载您的A记录,而没有B或C。但是,如果您尝试将这些实体传递回客户端,则序列化程序将遍历每个属性,从而使B和C集合的延迟加载失败,并为每个单独的A记录加载每个集合。当返回一个A的集合时,这比在查询中急于加载B和C时要差得多,因为如果返回5x A记录,则延迟加载调用将达到:
从B WHERE AId = 2中选择,...从
从C WHERE AId = 1中选择,...从
10个额外的SQL语句,而不是在一个初始(较大)SQL语句中包括所有相关的B和C行。您可以通过关闭EF延迟加载(关闭代理)来避免此性能陷阱,但是随后您将获得不反映实际数据状态的空集合。 (IMO实体应该始终完整地表示其数据状态,不要猜测丢失的数据是否只是没有加载,或者该实体实际上没有相关数据。)
扩展Select
如何提高性能的方法;假设您有一组订单,其中包含订单项列表,并且每个订单都与一个客户相关联。您需要订单号,订单项目的总成本以及客户名称。您不想为每个订单加载所有订单项和客户详细信息:
var orderDetails = context.Orders
.Where(o => o.OrderDate >= startDate && o.OrderDate < endDate)
.Select(o => new OrderViewModel
{
OrderId = o.OrderId,
OrderNumber = o.OrderNumber,
CustomerName = o.Customer.FullName,
Total = o.OrderLines.Sum(ol => ol.UnitPrice * ol.Quantity)
}).ToList();
这是EF和Linq的强大功能,有助于确保数据库完成大部分工作并仅返回您需要的字段。网络上的数据更少,应用服务器和客户端上的内存使用更少。