【问题标题】:"The mapping of CLR type to EDM type is ambiguous" with only one EF model“CLR 类型到 EDM 类型的映射不明确”只有一个 EF 模型
【发布时间】:2014-02-04 15:03:26
【问题描述】:

我有一个使用 Entity Framework 6 模型作为数据访问层的 ASP.NET 应用程序。它在自己的程序集中。

在一个单独的程序集中,我有一个业务逻辑层,其中有许多名称与实体模型类重叠的类。此程序集中的类位于与 DAL 模型不同的命名空间中。

所以,例如:

数据库表

  • 表A
  • 表B
  • 表C
  • 等等..

实体框架 DAL 类(程序集:ProjNameDAL)

  • OrgName.ProjName.DataAccess.TableA
  • OrgName.ProjName.DataAccess.TableB
  • OrgName.ProjName.DataAccess.TableC
  • 等等..

业务逻辑类(程序集:ProjNameBLL)

  • OrgName.ProjName.TableA
  • OrgName.ProjName.TableB
  • OrgName.ProjName.TableC
  • 等等..

在整个开发和部署过程中,我没有遇到任何问题。事实上,我已经在多个项目中使用过这种模式。但是,昨天我对数据库进行了架构更改,更新了我的 DAL 和 BLL,并编译了我的项目。当我尝试执行一些(不是全部)使用 DAL 的 BLL 方法时,我得到了可怕的 CLR/EDM 模糊类型映射错误:

CLR 类型到 EDM 类型的映射是不明确的,因为多个 CLR 类型与 EDM 类型“TableD”匹配。以前找到的CLR类型 'OrgName.ProjName.DataAccess.TableD',新发现的 CLR 类型 'OrgName.ProjName.TableD'。

我收到了 3 种重叠类型的此消息,这些类型甚至都没有在相关方法中使用。

如果我更改 BLL 类名称,这当然可以解决问题。但是,如果可能的话,我宁愿不必为我的命名约定添加前缀/后缀。

我已经阅读了使用多个 EF 模型的限制,但这里的条件似乎并不直接适用。另外,过去我有几乎相同的配置运行良好。谁能解释这个运行时错误以及如何避免它?

【问题讨论】:

标签: vb.net entity-framework


【解决方案1】:

我认为这个异常实际上是由我在 BLL 中修改的 LINQ to Entities 查询中的问题引起的。我最初忽略了这个变化,但是一旦我改变了“有问题的” BLL 类名,我就遇到了这个异常:

无法转换类型 'System.Collections.Generic.IEnumerable1[[OrgName.ProjName.bllTableB, ProjNameBLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' to type 'System.Collections.Generic.List1[[OrgName.ProjName.bllTableB, ProjNameBLL,版本=1.0.0.0,文化=中性,PublicKeyToken=null]]'。 LINQ to Entities 仅支持转换 EDM 原语或枚举 类型。

当我在以下示例中从GetTableAByID(Int32) 调用.ToList() 时引发了此运行时异常:

Public Class TableA

    Public Property TableAID as Integer
    Public Property TableBs as New List(Of TableB)()
    Public ReadOnly Property Amount as Decimal
        Get
            If Me.TableBs.Count > 0 Then
                Return Me.TableBs.Sum(Function(tb) tb.Amount)
            Else
                Return 0
            End If
        End Get
    End Property

    Public Shared Function GetTableAs() As IQueryable(Of TableA)
        Dim db As New DataAccess.ProjNameEntities()
        Return (
            From ta In db.TableAs
            Order By ta.PaidDate Descending
            Select New TableA With {
                .TableAID = ta.TableAID,
                .TableBs = (
                    From tb In db.TableBs
                    Where tb.TableAID = ta.TableAID
                    Select New TableB With {
                        .Amount = tb.Amount
                    }
                )
            }
        )
    End Function

    Public Shared Function GetTableAByID(TableAID as Integer) as List(Of TableA)
        Return (
            From ta in GetTableAs()
            Where ta.TableAID = TableAID
        ).ToList()
    End Function
End Class

Public Class TableB
    Public Property TableBID as Integer
    Public Property TableAID as Integer
    Public Property Amount as Decimal
End Class

显然从DbQuery<T> 转换为List<T> 应该没有问题,所以我怀疑异常消息只是让我大吃一惊。我决定查看查询,看看是否有什么东西导致了问题。果然,就是它所在的地方。

这段代码的违规部分似乎是我在List(Of TableB) 中选择了New TableB。我重构了类和查询以避免这种模式(我真正需要的是 TableB.Amount 的总和)并且所有错误都清除了。

如果能对这个问题以及由此产生的非常误导的例外情况有所了解,我会很高兴。

编辑: 我发现只需将.ToList() 添加到子查询的末尾也可以解决问题,从而增加了facepalm 因子:

.TableBs = (
    From tb In db.TableBs
    Where tb.TableAID = ta.TableAID
    Select New TableB With {
        .Amount = tb.Amount
    }
).ToList()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-15
    • 2012-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多