c# - 一对一关系不加载所有实体

标签 c# entity-framework entity-framework-5

我有一个(由于契约(Contract)限制而设计的和过度简化的)数据模型,应该如下所示:

public class ProvisionalData
{
    public int ProvisionalDataID { get; set; }
    public string Data { get; set; }

    public Lot Lot { get; set; }
}

public class Destination 
{
    public int DestinationID { get; set; }
    public string Name { get; set; }
}

public class LotDestination
{
    public int LotDestinationID { get; set; }
    public int DestinationID { get; set; }
    public DateTime Month { get; set; }

    public Destination Destination { get; set; }
}

public class Lot
{
    public int LotID { get; set; }
    public int ProvisionalDataID { get; set; }
    public int LotDestinationID { get; set; }


    public ProvisionalData ProvisionalData { get; set; }
    public LotDestination LotDestination { get; set; }
}

从 Lot 到 ProvisionalData 的关系是双方都需要的一对一关系。请注意,这不是整个模型,也不是关注的领域。问题在于配置一对一关系。

我与一对一映射流畅配置相关:

public class LotConfig : EntityTypeConfiguration<Lot>
{
    public LotConfig()
    {
        ToTable("Lot");
        HasKey(x => x.LotID);

        HasRequired(x => x.ProvisionalData)
            .WithRequiredDependent(x => x.Lot)
            .WillCascadeOnDelete(true);
    }
}


public class ProvisionalDataConfig : EntityTypeConfiguration<ProvisionalData>
{
    public ProvisionalDataConfig()
    {
        ToTable("ProvisionalData");
        HasKey(x => x.ProvisionalDataID);
    }
}

显示的其他关系实际上已建立 - 我已验证它们是在我的上下文中配置的,并且所有 IDbSet 都存在并正常运行。事实上,除了导航属性上的某些 ProvisionalData 实体未由以下查询填充外,此设置的所有内容都“有效”:

var lotDestination = db.lotDestinations
    .Where(x => x.DestinationId == destinationId && x.Month == month)
    .Include(x => x.Lots)
    .Include("Lots.ProvisionalData")
    .Include(x => x.Destination)
    .SingleOrDefault();    

在我的真实数据集中,此查询将返回一个包含 30 个地 block 的目的地。其中 16 个已加载临时数据导航属性。 14 没有。当我手动循环遍历每个 Lot 和 db.Entry(lot).Reference(ProvisionalData).Load() 时,这个问题仍然存在。当我检查这些条目时,对于 .IsLoaded,所有 30 个都返回 true。查询和 .Includes 似乎在做它们应该做的事情,但由于我不明白的原因,一些实体没有回来。我希望它是一些我看不到的简单东西,因为我已经盯着它看了太久了。

但是,当我将关系(忽略现有数据库约束)更改为与 ProvisionalData 实体的一对多关系时,如下所示:

public class ProvisionalData
{
public int ProvisionalDataID { get; set; }
public string Data { get; set; }

public IList<Lot> Lots { get; set; }
}

和一个像这样的新 Lot 配置:

public class LotConfig : EntityTypeConfiguration<Lot>
{
    public LotConfig()
    {
        ToTable("Lot");
        HasKey(x => x.LotID);

        HasRequired(x => x.ProvisionalData)
            .WithMany(x => x.Lots)
            .HasForeignKey(x => x.ProvisionalDataID);
    }
}

一切正常。这里唯一的缺点是这没有反射(reflect)数据库中的真实约束,因此您可以在技术上尝试将多个 Lots 添加到同一 block ProvisionalData,这会在尝试保存时中断。我可以自己构建逻辑来防止这种情况发生,但为什么我不能在 Entity Framework 中表达它?我的配置不正确吗?

同样有趣的是,当我将上述查询切换到这个愚蠢的版本以进行测试时(EF 中仍然存在一对一映射):

var quota = db.Lots
    .Where(l => l.LotDestination.DestinationID == destinationId && l.LotDestination.Month == m)
    .Include(x => x.ProvisionalData)
    .Include(x => x.LotDestination)
    .Include(x => x.LotDestination.Destination)
    .Select(x => x.LotDestination)
    .FirstOrDefault();

所有临时数据都会返回,但某些目的地不会。这向我暗示,它与在一对一中包含多个深度的导航属性有关。以前有其他人经历过这种行为吗?

最佳答案

除共享主键 1:1 关联情况外,EF 不正式支持 1:1 关联。

您正在做的是创建 1:many's 并试图告诉 EF 它确实是 1:1。问题是,db 模式实际上是一个 1:many 模式,EF 会在这里出现问题。

如果你的要求是1:1,那么你需要使用共享主键(两个实体有相同的主键),一个也把它当作外键。

关于c# - 一对一关系不加载所有实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18006324/

相关文章:

c# - wpf 工具提示未显示在用户控件或其子控件上

c# - 带有可选返回记录集的存储过程的 Entity Framework

c# - 我应该在哪里连接到上下文以获得更好的性能?

entity-framework-5 - EF 5 中的多个结果集

c# - 在 C# 中使用 Windows 应用程序执行 http 方法

c# - asp mvc View 模型验证属性

entity-framework - 更新多对多 Entity Framework 模型中的审计字段

asp.net-mvc-4 - 如何使用ELMAH MVC记录EntityValidation错误?

c# - 了解 Java/C# 中的抽象和接口(interface)

c# - 对象中的 EF6 AddOrUpdate 对象