[英]One-to-One Relationship Not Loading All Entities
我有一个(由于合同约束,人为地简化了)数据模型应如下所示:
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手的目的地。 这些批次中的16个已加载其ProvisionalData导航属性。 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);
}
}
一切正常。 唯一的缺点是,这并不能反映数据库中的真正约束,因此您可以从技术上尝试将多个批次添加到同一临时数据中,这在尝试保存时会中断。 我可以建立逻辑来防止这种情况发生,但是为什么我不能在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();
所有的临时数据都会返回,但某些“目的地”则不会 。 这向我暗示,这与在一对一的深度内包含多个级别的导航属性有关。 有没有其他人经历过这种行为?
EF在共享主键1:1关联情况下不正式支持1:1关联。
您正在执行的操作是创建1:1:1,然后尝试告诉EF它实际上是1:1。 问题是,db模式实际上是一个1:many模式,EF在这里会出现问题。
如果您的要求是1:1,则需要使用共享的主键(两个实体都具有相同的主键),并且也将其视为外键)。
我之前遇到的问题,我的解决方案使用的是1:many,因为如果POCOA包含POCOB
.Include(x => x.POCOA.POCOB)
真正将POCOB作为列表返回,因为我们知道它100%返回一条记录,因此在获取数据期间,我们可以说a.SingleOrDefault();。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.