我有两个保存家庭成员的表,当我使用include
来检索家庭成员时,生成的T-SQL就是我所期望的,但是当我看到来自VS的结果时,如下图所示,它看起来永无止境。
我的问题:
include
吗?POCO
public class Cust_ProfileTbl
{
[Key]
public long bintAccountNo { get; set; }
public string nvarCardName { get; set; }
public string varEmail { get; set; }
public virtual ICollection<Cust_ProfileFamilyTbl> profileFamilyParents { get; set; }
public virtual ICollection<Cust_ProfileFamilyTbl> profileFamilyChildren { get; set; }
}
public class Cust_ProfileFamilyTbl
{
[Key]
public int intProfileFamily { get; set; }
public long bintAccountNo { get; set; }
public long bintAccountNoMember { get; set; }
public virtual Cust_ProfileTbl custProfileParent { get; set; }
public virtual Cust_ProfileTbl custProfileChild { get; set; }
}
LINQ
var rs = from family in context.member.Include("profileFamilyParents.custProfileChild")
select family;
rs = rs.Where(x => x.bintAccountNo.Equals(1));
var result = rs.ToList();
on onModelCreating
modelBuilder.Entity<Cust_ProfileFamilyTbl>()
.HasRequired(m => m.custProfileParent)
.WithMany(t => t.profileFamilyParents)
.HasForeignKey(m => m.bintAccountNo)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Cust_ProfileFamilyTbl>()
.HasRequired(m => m.custProfileChild)
.WithMany(t => t.profileFamilyChildren)
.HasForeignKey(m => m.bintAccountNoMember)
.WillCascadeOnDelete(false);
答案 0 :(得分:2)
当人们在他们的应用程序中使用像EF这样的ORM时,很多时候应用程序设计都是由这个ORM和其模型中定义的实体驱动的。当应用程序是一个简单的&#34; CRUD&#34;应用,这不是问题,而是优势,因为你节省了很多时间。
然而,当事情开始变得更复杂时,一个&#34; ORM引导设计&#34;成为一个问题。看起来就是这样。
至少有两个问题,从评论中找到:
当出现这种情况时,最明智的做法是打破ORM与应用程序其余部分之间的紧密联系,这可以通过定义新类并将数据投影到其中来实现。让我们给出一个通用的ProfileDto
名称。
public class ProfileDto { ... }
DTO是这类类的通用名称:数据传输对象 - 但是,当它们具有特定用途时,它们可以获得其他名称,例如视图模型,当它们将被用作模型发送到MVC视图
然后,您需要做的是将查询结果投影到DTO中:
var model = theQuery.Select(i => new ProfileDto { a = i.a, b = i.b...}).ToList();
通过Dto的良好设计,您只能从数据库中恢复所需的数据,并且您将避免循环问题(通过不包括创建循环的导航属性)。
注意:很多时候人们使用映射器(例如AutoMapper或ValueInjecter来自动生成映射或映射的一部分
代码标准化是一个非常好的想法,直到它成为问题的根源。编写代码的主要目的是实现业务逻辑。如果代码标准化,技术或其他任何东西使得实现业务逻辑变得更加困难,而不是为解决方案做出贡献,那么它们就成了一个问题,所以你需要避免它们。
答案 1 :(得分:1)
您创建的映射是正常,但使用Include取决于其用法
使用Include取决于使用情况,例如,如果您想将其缓存在内存中,那么您可以使用include,其中您好像只使用显示Cust_ProfileTbl的属性 某些网格中的类,如果您想要显示Cust_ProfileFamilyTbl的详细信息,那么您可能不想使用include。但是如果您使用的是Automapper,请小心,因为当它尝试映射相关属性时,它将查询数据库。
当您执行ToList()时会消耗内存,因为您正在将查询结果加载到List集合中。如果您再次想要查询结果,那么您可以使用ToQueryable()或只是想迭代,您可以不将它们加载到List。