Moh*_*adr 5 c# linq entity-framework join
我有以下实体
//Active Auction Entity
public class ActiveAuction
{
public int Id { get; set; }
public string Title { get; set; }
public int? FirstAuctionId { get; set; }
public int? SecondAuctionId { get; set; }
public int? ThirdAuctionId { get; set; }
public virtual Auction FirstAuction { get; set; }
public virtual Auction SecondAuction { get; set; }
public virtual Auction ThirdAuction { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
// Auction Entity
public class Auction
{
public int AuctionId { get; set; }
public AuctionStatus AuctionStatus { get; set; }
public int? DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
// Department Entity
public class Department
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public int? AdminId { get; set; }
public virtual Admin Admin { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我正在试图做的是让Active Auctions与Auctions加载和Auction还Departments装我知道我应该写Include为被加载的每一个对象,以便由EF生成的SQL将连接语句选择对象有我
但这是现有的代码
using (var dc = DataContext())
{
await dc.Auction
.Include("Department.Admin")
.Where(i => i.Id == id && i.AuctionStatus == AuctionStatus.Accepted).ToListAsync();
return await dc.ActiveAuction.
SingleOrDefaultAsync(i => i.Id == id);
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何,但此代码工作,并返回ActiveAuctions包括所有所需的对象
我检查了针对数据库执行的SQL,并按预期生成单独的查询.
我想要一个解释,了解返回如何ActiveAcutions加载与其他提到的实体!!?
原因很简单.您很可能知道,Entity Framework会跟踪您从数据库中获取的实体,主要是检测对它们的更改,并在您调用时将这些更改应用于数据库SaveChanges.但是,这意味着到目前为止,EF上下文具有从数据库中提取的实体缓存.
编辑:正如@GertArnold在评论中正确指出的那样 - 我对动态代理的解释是完全错误的 - 即使ProxyCreationEnabled是这样也是这样false.真正的原因是关系修复,它在DetectChanges被调用时由实体框架执行(它在各种事件上隐式调用,例如将实体附加到上下文,或执行查询DbSet).在该关系修复期间,EF同步导航属性和外键,在您的情况下会导致您观察到的行为.有关MSDN中关系修复的更多信息
要验证这一点,您可以使用以下简单代码:
using (var ctx = new TestEntities()) {
ctx.Configuration.LazyLoadingEnabled = false;
ctx.Configuration.ProxyCreationEnabled = false;
var code = ctx.Codes.First();
var error = ctx.Errors.First();
Debug.Assert(Object.ReferenceEquals(error.Code, code));
}
Run Code Online (Sandbox Code Playgroud)
这里我首先获取一些实体(Code),然后我获取另一个具有导航属性Code的实体(Error).您看到延迟加载被禁用.以下断言将通过,因为error.Code和代码是相同的.NET对象,它确认它是从上下文缓存中获取的.