Entity framework 未加载的实体框架双向关系包括
这让我觉得自己像个白痴。实体框架应该相当简单,但我自己无法解决这个问题,显然我有一个基本的误解。我希望这不是一个愚蠢的问题——如果是的话,我很抱歉 三个代码优先对象,彼此相关Entity framework 未加载的实体框架双向关系包括,entity-framework,ef-code-first,breeze,Entity Framework,Ef Code First,Breeze,这让我觉得自己像个白痴。实体框架应该相当简单,但我自己无法解决这个问题,显然我有一个基本的误解。我希望这不是一个愚蠢的问题——如果是的话,我很抱歉 三个代码优先对象,彼此相关 public class Schedule { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid RowId { get; set; } public DateTime Start { get; set; }
public class Schedule
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public virtual ICollection<Charge> Charges { get; set; }
}
public class Charge
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public decimal Rate { get; set; }
public Type Type { get; set; }
}
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
}
因为virtual是一个导航属性,所以它应该使Breeze现在能够在不改变数据结构的情况下在关系中双向运行。但EF不喜欢这样。它告诉我:
无法确定服务器之间关联的主体端
类型“Core.Charge”和“Core.Type”。其主要目的是
必须使用
API或数据注释之间的关系
很公平。我能看出这是多么令人困惑。现在,我的理解是,如果在依赖类中定义外键,它必须是该类的主键。因此,我们将其改为:
public class Type
{
[Key, ForeignKey("Charge"), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public virtual Charge Charge { get; set; }
}
这似乎有效,但。。。当您请求计划时,它将停止加载任何类型信息。在包裹上乱搞似乎一点作用也没有
发生了什么事,我做错了什么?你确定要把ForeignKey放在RowId上,我想你可能想要定义这样的关系
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public int ChargeId { get; set; }
[ForeignKey("ChargeId")]
public virtual Charge Charge { get; set; }
}
您不仅向现有模型/关系添加了导航属性(
Type.Charge
)。相反,您已将关系从一对多完全更改为一对一关系,因为默认情况下,如果一个关系只有一个导航属性,EF将采用一对多关系。通过更改,您已经配置了一对一关系
这些关系具有不同的外键:原始的一对多关系在Charge
表中有一个单独的外键(可能命名为Type_RowId
或类似名称)。新关系的外键位于表Type
的另一侧,它是主键RowId
。与计划一起加载的费用
可能没有任何具有相同主键的相关类型
,因此不会加载类型
如果您确实希望仅在另一端使用导航属性来重现旧的(一对多)关系,则必须将集合添加到Type
,而不是单个引用:
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public virtual ICollection<Charge> Charges { get; set; }
}
公共类类型
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
公共Guid RowId{get;set;}
公共字符串类型名{get;set;}
公共虚拟ICollection费用{get;set;}
}
感谢您的帮助。那你怎么称呼钥匙呢?“ChargeId”不是模型中任何属性的名称。尝试了“Charge”和“RowId”-这两种方法都会再次导致“无法确定关联的主体端”错误。您可以在类型模型中定义键名。好的,我的理解完全不正确。我曾假设,如果两端都没有指定为集合,EF将产生一对一的关系——这就是这里电荷和类型之间所需要的全部关系。回到文档中。@mattstrower:One-to-One意味着没有两个Charge
s可以拥有相同的类型。在您的业务逻辑中是这样吗?不是在同一个计划中,不是。一个计划有许多费用,每个费用必须是不同的类型。类型与费用在一个单独的表中,只是因为它在其他地方使用,否则它们可能是同一对象的一部分。@mattstrower:但是如果Charge1
在Schedule1
中,而Charge2
在另一个schedule2
中,这两种费用可以具有相同的类型吗?如果是,您肯定不能在费用
和类型
之间使用一对一关系。它必须是一对多。单个计划中的carges类型必须唯一的限制是应用程序业务逻辑,您无法通过任何映射配置来确保这一点。当然,您是正确的。打勾。我敢肯定,当我使用SQL来绘制它时,这似乎更容易。谢谢
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public int ChargeId { get; set; }
[ForeignKey("ChargeId")]
public virtual Charge Charge { get; set; }
}
public class Type
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid RowId { get; set; }
public string TypeName { get; set; }
public virtual ICollection<Charge> Charges { get; set; }
}