【问题标题】:Entity Framework Map With Fake Foreign Key Property具有假外键属性的实体框架映射
【发布时间】:2017-06-27 04:44:13
【问题描述】:

我的模型:

class FooEntity
{
    [Key]
    int Id { get; set; }

    [ForeignKey("Bar"), Column("other_id")]
    int OtherId { get; set; } // <-- This should be the FK

    virtual BarEntity Bar { get; set; }
}

class BarEntity
{
    [Key]
    int Id { get; set; }

    [Column("other_id")]
    int OtherId { get; set; } // <-- This is the other side of the FK
}

基本上我想重现这个 SQL:

select *
from foo f
left join bar b on b.other_id = f.other_id -- AND other conditions to "guarantee" uniqueness

但是使用模型构建配置:

modelBuilder.Entity<FooEntity>()
.HasOptional(f => f.Bar)
.WithRequired()
.Map(m => m.MapKey("other_id"))
.WillCascadeOnDelete(false);

我最终得到错误:“类型中的每个属性名称必须是唯一的。属性名称 'other_id' 已定义。”但是当我添加时:

modelBuilder.Entity<BarEntity>().Ignore(b => b.OtherId);

在其他配置之前,我收到错误消息:“LINQ to Entities 不支持指定的类型成员 'OtherId'。仅支持初始化程序、实体成员和实体导航属性。”

那么我怎样才能让它工作呢?更改底层数据结构绝对不是一种选择。

【问题讨论】:

    标签: c# entity-framework linq


    【解决方案1】:
    • 在 EF6 中,FK 必须指向 PK。
    • 在您的 RDBMS 中,它可能取决于实现。只要存在唯一索引约束,Sql Server 将允许 FK 返回到非 PK 列。其他 RDBMS 可能允许也可能不允许。

    我建议您省略 FK 关系,当您需要手动检索这两个实体时,请在您的 Linq/Lambda 语句中包含联接。

    【讨论】:

    • 澄清一下,EF6 中的 FK 必须指向 PK。在 SQL Server 和 EFCore 中,FK 可以引用任何候选(即唯一)键。
    • 不完全。在 EF6 中,实体只能有一个键(可能是复合键)。 Entity's Key 列应该是 RDBMS 中的 PK 或唯一索引,但如果您在数据库中有多个键,您可以选择任何一个作为您的 Entity Key。但是 EF 中的所有 FK 都必须指向那个 Key。
    【解决方案2】:

    你想要完成的事情没有捷径;您将需要手动创建查询,类似于:

    dbContext.Foos
        .GroupJoin( 
            dbContext.Bars, 
            f => f.OtherId, 
            b => b.OtherId,
            ( foo, bars ) => new { foo, bars } )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-11
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多