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

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

因此,例如:

数据库表


表A
表B
表C
等等..


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


组织名称.ProjName.DataAccess.TableA
组织名称.ProjName.DataAccess.TableB
组织名称.ProjName.DataAccess.TableC
等等..


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


组织名称.ProjName.TableA
组织名称.ProjName.TableB
组织名称.ProjName.TableC
等等..


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


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


我收到3种重叠类型的消息,而所讨论的方法中甚至都没有使用。

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

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

最佳答案

我认为此异常实际上是由我在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,版本= 1.0.0.0,文化=中性,PublicKeyToken =空]]”。
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)的地方。我重构了类和查询以避免这种模式(我真正需要的只是TableB.Amount的总和),并且清除了所有错误。

如果此问题以及由此产生的非常误解性例外,我希望可以为您提供帮助。

编辑:
通过发现仅将.ToList()添加到子查询的末尾也可以解决此问题,我提高了facepalm因素:

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

10-06 12:19