我想做一个返回Parent表的所有记录的LINQ查询,并包含Child(如果适用)。我知道我可以使用DefaultIfEmpty()
进行LINQ连接,但是我必须输出一个ViewModel。我想获得实际父类的IQuerable<Parent>
。
所以,如果我有这些课程:
public class Parent
{
[Key]
public int ParentId {get; set;}
public string ParentName {get; set;}
public int? MyChildId {get; set;}
[ForeignKey("MyChildId")]
public virtual Child MyChild {get; set;}
public bool IsActive {get;set;}
}
public class Child
{
public int ChildId {get;set;}
public string ChildName {get;set;}
}
在LINQPad中,如果我这样做:
var results = db.Parent.Where(ra => ra.IsActive);
results.Dump();
我得到111条记录。
如果我这样做:
var results = db.Parent.Where(ra => ra.IsActive);
var results2 = (from r in results
select new
{
ParentId = r.ParentId,
ParentName = r.ParentName,
MyChildId = r.MyChildId
});
results2.Dump();
我还收到111条记录。
但如果我这样做:
var results = db.Parent.Where(ra => ra.IsActive);
var results2 = (from r in results
select new
{
ParentId = r.ParentId,
ParentName = r.ParentName,
MyChildId = r.MyChildId,
IsActive = r.IsActive,
MyChildName = r.MyChild == null ? null : r.MyChild.ChildName
});
results2.Dump();
我只得到50条记录。这些是有孩子的50条Parent
条记录。如果他们没有孩子,他们就不会回来。
生成的SQL如下所示:
SELECT
[Extent1].[ParentId] AS [ParentId],
[Extent1].[ParentName] AS [ParentName],
[Extent1].[IsActive] AS [IsActive],
[Extent2].[ChildName] AS [ChildName]
FROM [dbo].[Parent] AS [Extent1]
INNER JOIN [dbo].[Child] AS [Extent2] ON [Extent1].[MyChildId] = [Extent2].[ChildId]
WHERE [Extent1].[IsActive] = 1
如何获得包含所有111条Parent
条记录的结果集,即使它们没有子级,但是包含Child
元素,如果它们在那里?
更新 所以,我可能会撒谎。为了简单起见,我发布了上面的内容,但为了防止它有用,下面是代码所做的更接近的示例:
public class Parent
{
[Key]
public int ParentId {get; set;}
public string ParentName {get; set;}
public int? MyChildId {get; set;}
[ForeignKey("MyChildId")]
public virtual Child MyChild {get; set;}
[ForeignKey("MyChildId")]
public virtual StepChild MyStepChild {get; set;}
public bool IsActive {get;set;}
}
public class Child
{
public int ChildId {get;set;}
public string ChildName {get;set;}
}
public class StepChild
{
public int StepChildId {get;set;}
public string StepChildName {get;set;}
}
答案 0 :(得分:0)
有时候很难分辨EF幕后发生的事情,你可能会遇到一些非显而易见的行为,我通常在这种情况下做的事情 - 检查实际生成的SQL查询,并调整LINQ查询直到它在逻辑上等同于我期望的查询。 这不是最好的方法,因为它取决于可以改变的实现细节,但有时它是克服EF错误的唯一方法。 您可以使用数据库调用的ObjectQuery或EF logging and interception来获取实际的SQL查询
答案 1 :(得分:0)
你需要两个单独的FK属性吗? personAssigneeId和另一个int? organizationAssigneeId。这些FK指向两个完全不同的实体。如果为两个独立的实体重用相同的FK,则EF无法正常工作,每个实体需要一个FK。
答案 2 :(得分:0)
默认情况下(或要求)您的外键不可为空,因此您需要告诉EF它应该是可选的。要实现它,您需要覆盖以下modelBuilder方法:
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
并配置您的Entity外键:
modelBuilder.Entity<Parent>().HasOptional(e => e.MyChild).WithMany();
您可以在此处查看详细信息:http://blog.staticvoid.co.nz/2012/7/17/entity_framework-navigation_property_basics_with_code_first