发出加载父实体的子实体的问题.单向映射和1到0..1与共享主键的关系?

Mad*_*ady 2 entity-framework ef-code-first entity-framework-ctp5 entity-framework-6

当我尝试加载父实体的子实体时,它加载默认值.如果我尝试显式加载它会抛出异常 违反Multiplicity约束."CodeFirstNamespace.Association_Customer"关系的角色"Association_Customer_Target"具有多重性1或0..1.检索复杂图形的子实体时抛出此异常.

我有一个图表关联,它有一个子实体Customer,关系为1到0或1,并且具有独立关联.*主键*是共享的.我正在使用EF6.延迟加载已启用.

public class Association
{
   public virtual long Id { get; set; }
   public virtual string ExternalId { get; set; }
   public virtual int OrganizationId { get; set; }
   public virtual AssociationType AssociationType { get; set; }
   public virtual Customer Customer {get; set;}
   public Association()
   {
       Customer = new Customer();
   }
}
Run Code Online (Sandbox Code Playgroud)

客户类.

public class Customer
{
  public virtual long Id { get; set; } //Shared primary key
  public virtual ICollection<Item> Items {get; set;}
  public virtual ICollection<Complaint> Complaints {get; set;}
  public customer()
  {
    Items = new List<Item>();
    Complaints = new List<Complaint>();
  }
}
Run Code Online (Sandbox Code Playgroud)

映射是单向的:

public class AssociationMapping:EntityTypeConfiguration<Association>
{
   public AssociationMapping() : base()
   {
     HasKey(x => x.Id);
     Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
     Property(x => x.ExternalId).IsRequired();
     Property(x => x.OrganizationId).IsRequired();
     Property(x => x.AssociationType);
     HasOptional(x => x.Customer).WithRequired().WillCascadeOnDelete();
   }
}

public class CustomerMapping : EntityTypeConfiguration<Customer>
{
  public CustomerMapping ():base()
  {
    HasKey(x => x.Id);
    Property(x => x.Id);
    HasMany(x => x.Items)
       .WithOptional()
       .HasForeignKey(key => key.CustomerId)
       .WillCascadeOnDelete();
    HasMany(x => x.Complaints)
      .WithOptional()
      .HasForeignKey(key => key.CustomerId)
      .WillCascadeOnDelete();
  } 
}
Run Code Online (Sandbox Code Playgroud)

当我加载我的关联实体时,它完全加载但子实体Customer在我尝试明确加载Customer时加载了默认值,它会抛出异常.

 var dbassociation = Single<Association>(x => x.OrganizationId== asso.organizationId && x.ExternalId == asso.ExternalId && x.AssociationType == asso.AssociationType);
 dbassociation.Customer = Single<Customer>(x => x.id == dbassociation.id);
Run Code Online (Sandbox Code Playgroud)

[更新:单一方法]

public TEntity Single<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>>criteria) {
  return Context.Set<TEntity>().SingleOrDefault(criteria);   }
Run Code Online (Sandbox Code Playgroud)

出于测试目的,我试图通过删除关联类中的Customer属性上的虚拟并尝试跟随但是它会引发相同的扩展

Context.Configuration.LazyLoadingEnabled = false;
Context.Entry<Association>(dbassociation).Reference<Customer>(pa => pa.Customer).Load();
Run Code Online (Sandbox Code Playgroud)

我也尝试过抛出相同的异常

var dbassociation = Context.Set<Association>().Include("Customer").SingleOrDefault(x => x.OrganizationId== asso.organizationId && x.ExternalId == asso.ExternalId && x.AssociationType == asso.AssociationType);
Run Code Online (Sandbox Code Playgroud)

现在我得出结论,虽然我使用不同的方法来检索异常是一样的.问题在于我猜测的映射.感谢您的意见和建议.

Sla*_*uma 11

尝试删除

Customer = new Customer();
Run Code Online (Sandbox Code Playgroud)

来自Association构造函数.实例化导航引用是已知问题的来源(与实例化空导航集合相反,这很好).这就是为什么你得到一个Customer默认值的原因.我不确定它是否也解释了异常,但我可以想象当Association加载并附加到上下文时,与Customer默认构造函数EF创建的未初始化一起检测到具有无效键的相关实体:Association具有(我假设)一个关键值!=0和相关Customer用钥匙==0(因为它从来没有被初始化为其它值).但是,在共享主键关联中,两个键值必须匹配.因为它们没有,它可能会导致异常(但是这个异常并不能很好地指出问题的根源).

只是一个猜测.