entity-framework - Entity Framework 双向关系未加载包括

标签 entity-framework ef-code-first breeze

这让我感觉自己像个白痴。 Entity Framework 应该相当简单,但我自己无法解决这个问题,显然我有一个根本性的误解。我希望这不是一个白痴问题 - 如果是的话,抱歉。

三个代码优先对象,彼此相关。

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; }
}

当我查询这个时,我想要所有相关的类型,所以:

        Schedule currentSchedule = _Context.Schedules
                .Include("Charges.Type")
                .Where(cs => cs.Start < dateWindow && cs.End > dateWindow)
                .First();

在 C# 中,这一直运行良好。

问题的出现是因为我们并没有停留在 C# 上,而是将数据传递到一个名为 Breeze 的 JavaScript 库,以平滑客户端的数据操作。 Breeze 有一个错误/功能,要求在两端指定对象之间的 EF 关系。因此,当我执行上面的查询时,我最终不会得到任何类型,因为它们与 Charge 的关系没有直接指定。

所以我把它改成这样:

public class Type
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid RowId { get; set; }
    public string TypeName { get; set; }
    public virtual Charge Charge { get; set; }
}

因为 virtual 是一个导航属性,所以这应该使 Breeze 现在能够在不改变数据结构的情况下双向跨越关系。但EF不喜欢这样。它告诉我:

Unable to determine the principal end of an association between the types 'Core.Charge' and 'Core.Type'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations

很公平。我知道这可能会令人困惑。现在,我的理解是,如果您在依赖类中定义外键,它必须是该类的主键。所以我们将其更改为:

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; }
}

这似乎有效,但是......当您询问时间表时,它会停止加载任何类型信息。乱搞包含似乎根本没有做任何事情。

发生了什么事,我做错了什么?

最佳答案

您不仅向现有模型/关系添加了导航属性 (Type.Charge)。相反,您已将关系从一对多关系完全更改为一对一关系,因为默认情况下,如果关系只有一个导航属性,则 EF 会假定一对多关系。通过您的更改,您已经配置了一对一关系。

这些关系具有不同的外键:原始的一对多关系在 Charge 表中具有单独的外键(可能名为 Type_RowId 或类似名称)。您的新关系在表 Type 的另一侧具有外键,并且它是主键 RowId。您与 Schedule 一起加载的 Charge 可能没有任何具有相同主键的相关 Type,因此没有 类型已加载。

如果您确实想在另一侧仅使用导航属性来重现旧的(一对多)关系,则必须向 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; }
}

关于entity-framework - Entity Framework 双向关系未加载包括,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17747396/

相关文章:

entity-framework - 如何为 Breeze 实体生成 typescript 接口(interface)/定义

c# - "Attaching an entity of type T failed because another entity of the same type already has the same primary key value"

c# - Entity Framework 6 中的 Fluent Api 不兼容 Entity Framework Core

entity-framework - EF 4.1 CF : CREATE DATABASE permission denied in database 'master'

entity-framework - 如何找到流利的API映射了哪个表?

c# - Entity Framework 中的外键未正确更新

entity-framework - ValidationResult.Success 字段的用途是什么?

c# - 将 Entity Framework 与 Web 代理一起使用

angularjs - Angular -ui-select2和breezejs : load ajax list after typing in 2 characters

javascript - Breeze js : inlineCount is incorrect when sorting by navigation property