“CLR类型到EDM类型的映射是模糊的”,只有一个EF模型

时间:2014-02-04 15:03:27

标签: vb.net entity-framework

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

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

所以,例如:

数据库表

  • TableA
  • 表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模型的局限性,但这些条件似乎并不适用于此。另外,过去我的配置几乎相同。任何人都可以解释这个运行时错误以及我如何避免它吗?

1 个答案:

答案 0 :(得分:2)

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

  

无法转换类型   “System.Collections.Generic.IEnumerable 1[[OrgName.ProjName.bllTableB, ProjNameBLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' to type 'System.Collections.Generic.List 1 [[OrgName.ProjName.bllTableB,   ProjNameBLL,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]'。   LINQ to Entities仅支持转换EDM原语或枚举   类型。

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

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>应该没有问题,所以我怀疑这些异常消息只是让我进行了一次疯狂的追逐。我决定查看查询以查看其中的某些内容是否导致了问题。果然,那就是它。

此代码的违规部分似乎是我在New TableB中选择List(Of TableB)的地方。我重构了这个班级&amp;查询以避免这种模式(我真正需要的是TableB.Amount的总和)并清除所有错误。

如果有任何问题可以解决这个问题以及导致的非常误解的例外,我会很高兴。

编辑: 我通过发现仅在子查询的末尾添加.ToList()来解决问题,从而增加了facepalm因素:

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