EF4 Poco 问题映射类型相同的名称相同的程序集不同的命名空间

Posted

技术标签:

【中文标题】EF4 Poco 问题映射类型相同的名称相同的程序集不同的命名空间【英文标题】:EF4 Poco Issue Mapping Types Same Name Same Assembly Different Namespaces 【发布时间】:2011-03-22 05:08:27 【问题描述】:

我在使用 EF4Proxy Pocos 时遇到问题。

我在同一个程序集中有 2 个同名的类,但不同的命名空间

QuoteModels.CashPayment
OrderModels.CashPayment

这可以正常编译,但在运行时 EF 会抛出以下异常:

指定的架构无效。错误: \r\nCLR 类型到 EDM 的映射 类型不明确,因为多个 CLR 类型匹配 EDM 类型 '现金支付'。以前找到的CLR 键入“QuoteModels.CashPayment”,新 找到 CLR 类型 'OrderModels.CashPayment'

是否有一种解决方法可以使具有不同命名空间的同一程序集中具有相同名称的类与 Ef4 一起使用?

我是否必须给它们起不同的名称或将它们移动到另一个程序集中?

【问题讨论】:

我们这里也有同样的问题。我在 MSDN 上发布了一个关于这个“功能”的问题。请投票(在 MSDN 上)以获得更快的结果:social.msdn.microsoft.com/Forums/hu-HU/adodotnetentityframework/… 这应该是对该功能进行投票的更好地方:data.uservoice.com/forums/… 【参考方案1】:

我找到了解决方法。这是一个非常明显的变通方法,但并不理想,但我认为在 EF5 出来解决这个问题之前,我认为它对我们来说已经足够好了。

简答:只需重命名一个或两个模棱两可的实体,例如:2x Person 重命名为:Personal_PersonWork_Person 基于 PersonalContextWorkContext .

详细回答:在我们的场景中,我们使用的是 DB 优先的方法(我们正在重写一个遗留应用程序,而数据库更改最少)。我们的数据库包含数百个表,因此我没有使用单个 EDMX/上下文,而是使用多个 EDMX/上下文(每次我尝试添加超过一半的表时,EDMX 都会发出嘶哑的声音)。但是,有些表需要存在于多个 EDMX/上下文中。

为了讨论,假设我们有一个包含以下表格的简单数据库:

Person Family Relationship Address Business Employee

另外,为了讨论,让我们假设存在于多个上下文中的任何表都会导致这个问题(正如我在 cmets 中对 Devart 的回答所说的那样,这不是真的,我不明白为什么它有时会起作用)。

现在假设我们要创建两个上下文:

PersonalContext:

Person Family Relationship Address

WorkContext:

Person Business Address Employee

在这种情况下,PersonAddress 都会导致我们的问题。所以我们在 EDMX 映射中要做的就是将实体重命名为 Personal_Person/Work_PersonPersonal_Address/Work_Address

如上所述,这是一个非常明显的解决方法,但并不理想,但由于 EF 不考虑命名空间并且严格按名称(不是真实身份,只是名称),一个选项是你名字中的命名空间。

现在我仍在争论是否要这样做,或者是否为每个实体命名(Personal_PersonPersonal_FamilyPersonal_RelationshipPersonal_AddressWork_Person、@987654353 @、Work_AddressWork_Employee) 用于一致性和 Intellisense 友好性(保持所有实体按正确的字母顺序排列),因为实际上,命名空间属于名称之前而不是之后,但这是一个判断调用,并不是很重要为问题提供解决方案。

希望对你有帮助!!

【讨论】:

只是为了跟进这个问题,两年半之后,我们仍然有这个解决方法。它完美地解决了这个问题,没有明显的副作用。唯一的问题是确保Entity Set Name 设置正确。换句话说,当您将Person 重命名为Person_Work 时,请确保复数版本仍然命名为People 而不是Person_Works。我们还对实体名称部分之后的命名空间部分进行了标准化。这样我们就可以拉起Person* 并简单地pick 命名空间,而不必先考虑命名空间。 多年后更新:此解决方案仍然适用于 EF6。但是,我现在也能够使用 EF6 成功地将一个非常大的数据库(400 多个表)放入单个上下文中,并且加载时不会乱作一团,因此我对这个解决方案的需求已经大大减少了。 有谁知道 LinqToSQL 是否也存在这个问题? @Mfusiki:我建议你问一个不同的问题。这是与 Entity Framework 不同的产品。【参考方案2】:

看看this post。 Derek 的评论似乎处理了同样的问题,他没有收到微软的任何答复。

【讨论】:

他做到了:@Derek 这是故意的。您可以将 POCO 类放在您想要的任何名称空间中。实体框架用于检测实体上的哪些属性与模型中实体的属性匹配的约定机制不使用命名空间。重要的是类型名称(没有命名空间)与模型(edmx/csdl 文件)中的 EntityType 名称匹配。需要注意的一个方面是,如果您有多个具有相同名称但位于不同名称空间的类型。因为我们没有考虑命名空间,所以我们检测到我们发现了多种类型并抛出了异常。杰夫 感谢您的澄清。知道为什么他们是故意这样做的吗?这在未来会改变吗?我希望能够在同一个程序集中拥有 POCO,但不同的命名空间具有相同的名称,你知道吗? 没有。我现在正在为此苦苦挣扎,需要找到解决方案。我的问题是,并非所有与此匹配的课程都会导致问题。它似乎只是由充当多对多关系的表引起的。例如,在您的场景中,如果CashPayment 是一个存储财务信息的标准表,那么它对我来说就像预期的那样工作!但是,如果 CashPayment 只是一个指向 0 对多 CashTransaction 实体的多对多表(因此使 CashPayment 成为 CashTransaction 类型的集合),那么它会在 CashPayment 上爆炸桌子。有意义吗? 今天碰到这个,首先使用代码。在这种情况下,这个问题显然很愚蠢,因为代码本身非常清楚要使用哪种类型。似乎是 Leaky Abstraction 的一个案例,其中代码优先 API 被放在旧的 EF 之上。 有谁知道这是否已被报告为 MSDN Connect 上的错误?我的搜索都没有发现任何东西,但我可能会错过它。无论 EF 团队是否认为这是一个错误,它都是一个错误。为什么有人希望 EF 随机通过 DbContext 类中指定的命名空间以外的命名空间进行侦听?它违反了我对 C# 的了解。【参考方案3】:

我刚刚遇到了类似的问题。我花了一段时间来确定模式,但在我的上下文中,当我有两个模型都具有两个相同的实体时,就会出现问题。

在我的一个模型上,我有以下实体(“->”表示与方向的关系): Users -> Authentication -> Authorization(用户经过身份验证然后授权)。

另一方面,我有这些实体: Authentication -> Authorization -> InvoiceGeneration(经过身份验证和授权的用户生成发票)。

在使用这两个模型运行我的应用时,我遇到了与原始海报相同的错误。

事实证明,当我从第二个模型中删除 Authentication 实体时,我的问题消失了,因此 似乎 EDM 到 CLR 映射器无法处理具有相同类型“父级”的实体” 关系(在我的两个模型上,AuthorizationAuthentication “先于”。 对不起,非科学的关系描述:)

【讨论】:

【参考方案4】:

我所做的是删除一个重复的实体,并为另一个实体创建一个具有已删除实体属性的部分类

例子:

namespace Namespace1

 class Talk
 
  public int TalkId get; set;
 

namespace Namespace2

 class Talk
 
  public int TalkId get; set;
  public string SomeExtraInfo get; set;
 

结果:

namespace Namespace1

 class Talk
 
  public int TalkId get; set;
 

namespace Namespace1

 partial class Talk
 
  public string SomeExtraInfo get; set;
 

希望对某人有所帮助

【讨论】:

以上是关于EF4 Poco 问题映射类型相同的名称相同的程序集不同的命名空间的主要内容,如果未能解决你的问题,请参考以下文章

EF 4.3 代码首先在同一类型上映射 N:M

MVC3 应用程序/服务层/存储库层/POCO 类/EF4 - 问题!

EF4 CTP5 - 映射没有对象引用的外键?

EF4 POCO:快照与 WCF 上的自我跟踪

使用 EF4 的 POCO 模板时“找不到元数据信息”?

保存 EF4 POCO 对象的更改时更新关系