【问题标题】:Creating Fluent Relationship not based on primary key(s)创建不基于主键的流畅关系
【发布时间】:2013-02-20 10:26:07
【问题描述】:

我有一个简单的 SQL 查询,我试图将它与 Fluent API 和 Entity Framework 一起使用,但我做的很粗糙。这是查询:

 SELECT     
  tbl1.Column,      
  tbl2.Column,  
  tbl3.Column,
  tbl4.Column
 FROM dbo.Table1 tbl1  
 INNER JOIN dbo.Table2 tbl2 ON tbl1.[Table 2 ID FK] = tbl2.ID
 LEFT JOIN dbo.Table3 tbl3  ON tbl3.[NonKeyColumn] = tbl2.[NonKeyColumn]
 LEFT JOIN dbo.Table4 tbl4 ON tbl4.[Table1FK] = tbl1.ID

我的问题是 Table2 和 Table3 上的连接;这些列不是任一表的主键,并且在两个表中的命名完全不同。我的表之间的关系是这样的:

表1 表2

表3 表2

表4 > 表2

如何在 Table2 上编写一个关系,该关系将在两个给定列上加入 Table3?

我认为这是朝着正确方向迈出的一步(在 Table1 中定义):

 this.HasMany(e => e.Table2)
     .WithOptional(e => e.Table1)
     .HasForeignKey(tlb2 => tbl2.Column)

但由于无法将 Table1 中的列与 Table2 中的列关联,所以我走到了死胡同。谢谢!

【问题讨论】:

  • 你已经拥有实体了吗?
  • 是的。它可能会提到我使用的是 Code First 方法,因此没有 EDMX 来设置关联或类似性质的东西。
  • 我觉得如果你能把真实的实体贴在这里让我们看到实际情况就好了。

标签: c# .net entity-framework ef-code-first


【解决方案1】:

你不能写出这样的关系。这将要求 NonKeyColumn 成为 Table2 中的唯一键,但 EF 还不支持唯一键 => EF 不支持基于非主键的关系。

【讨论】:

    【解决方案2】:

    正如 Ladislav 指出的那样,您无法建立基于非键列的关系,但这种情况在 EF 中不一定不可能完成......它只是非常混乱。为了实现我想要只使用 LINQ 和 EF 做的事情,查询最终基本上具有与此类似的结构:

     var values = context.Table1.Select()
                            .GroupJoin(
                                        context.Table2.Select(),
                                        detail => detail.ID,
                                        entry => entry.ID,
                                        (detail, entry) =>
                                            new { //select columns })
                                         .DefaultIfEmpty()
                                         .GroupJoin(
                                                context.Table3.Select(),
                                                entry => entry.Id,
                                                check => check.NonKeyColumn,
                                                (entry, check) => new {//select additional columns})
                                         .DefaultIfEmpty()
                                         .GroupJoin(
                                                context.Table4.Select(),
                                                entry => entry.ID,
                                                transactions => transactions.ID,
                                                (entry, transactions) => new {//select additional columns})
                                         .DefaultIfEmpty();
    

    使用 GroupJoins,我能够获得我需要的 LEFT JOIN 行为(.Join 执行 INNER JOIN)并得到我预期的数据集。话虽如此,我最终放弃了这种方法,只是简单地提出了一种观点,将我的呼吁简化为:

      context.ViewTable.Select...
    

    这只是告诉您,仅仅因为您可以做某事并不一定意味着您应该这样做。 ;]

    【讨论】:

      猜你喜欢
      • 2016-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 2017-08-29
      相关资源
      最近更新 更多