gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 16:09:41 25 4
gpt4 key购买 nike

我有一个(由于契约(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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com