80

请问有人可以帮我解决这个错误吗?

指定的架构无效。错误:

CLR 类型到 EDM 类型的映射不明确,因为多个 CLR 类型与 EDM 类型“City_DAL”匹配。之前发现的CLR类型'CeossDAL.City_DAL',新发现的CLR类型'CeossBLL.City_DAL'。

我有 DAL 的主要问题,它包含 EF 和 BLL,它包含相同的 DAL 类,但名称空间不同,这就是导致问题的原因

我不知道如何摆脱这些问题,你能帮帮我吗?

如果有人给我示例以使用带有 EF 的 n 层架构,我也将不胜感激

谢谢

4

15 回答 15

77

不要使用具有相同非限定名称的类 - EF 仅使用类名称来标识 EDMX 中映射的类型(忽略命名空间) - 这是允许将不同命名空间中的类映射到单个模型的约定。您的问题的解决方案是在 BLL 中以不同的方式命名您的类。

于 2013-02-18T19:37:09.187 回答
45

解决方法:更改两个相同类之一的属性。

EF 匹配类名和类属性。所以我只是更改了其中一个 EF 对象的属性名称,错误就消失了。

正如@Entrodus 对其他答案之一的评论:

仅当两个类具有相同的名称和相同的参数集时,才会发生 EF 冲突。

于 2015-10-16T16:27:44.780 回答
10

这个MSDN 论坛问题可能会有所帮助。它建议将 BLL 和 DAL 类放在单独的程序集中。

于 2013-03-06T08:47:56.650 回答
8

在某些情况下,这更像是一个症状而不是实际问题。对我来说,当我尝试在 Linq 查询中调用函数而不首先调用 .ToList() 时,它通常会弹出。

例如,将我带到这里的错误是因为我这样做了:

var vehicles = DB.Vehicles.Select(x => new QuickSearchResult()
{
    BodyText = x.Make + " " + x.Model + "<br/>"
    + "VIN: " + x.VIN + "<br/>"
    + "Reg: " + x.RegistrationNumber +"<br/>"
    + x.AdditionalInfo
    type = QuickSearchResultType.Vehicle,//HERE. Can't use an enum in an IQueryable.
    UniqueId = x.VehicleID
});

我必须调用 .ToList(),然后遍历每个项目并为其分配类型。

于 2017-02-08T09:29:40.497 回答
8

对于 EF 6.x,我在https://github.com/aspnet/EntityFramework/issues/941找到了一些注释,并通过向 EDM 类型添加注释在我的解决方案中解决了这个问题。

我手动编辑了 EDMX 文件并更改了如下一行:

<EntityType Name="CartItem">

对此:

<EntityType Name="CartItem" customannotation:ClrType="EntityModel.CartItem">

或者如果您在其他地方有现有类型,则使用它:

<EntityType Name="CartItem" customannotation:ClrType="MyApp.CartItem, MyApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">

其中EntityModel是用于我的 EF 模型的命名空间,而MyApp是业务对象的命名空间

于 2017-07-05T16:16:31.603 回答
2

I got the error above because for both connection strings, I had the same value for metadata specified in my main project's config file, like below:

<add name="EntitiesA" connectionString="metadata=res://*/EntitiesA.csdl|res://*/EntitiesA.ssdl|res://*/EntitiesA.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

<add name="EntitiesB" connectionString="metadata=res://*/EntitiesA.csdl|res://*/EntitiesA.ssdl|res://*/EntitiesA.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

I ended up copying the correct connection string from the EntitiesB's project's config file.

于 2018-02-02T04:46:55.630 回答
1

提出问题时这可能不可用,但另一种解决方案是删除 EDMX 并将其重新创建为代码优先实体数据模型。在 EF6 中,通过代码优先,您可以从不同的模型命名空间映射两个具有相同名称的类,而不会产生冲突。

要在 Visual Studio (2013) 中创建实体数据模型,请转到“添加”>“新项目...”>“ADO.NET 实体数据模型”。请务必选择“数据库中的代码优先”选项。

于 2017-01-31T23:04:39.937 回答
0

您可能会收到此错误的另一个原因是:如果您使用具有 edmx 文件的 Assembly.LoadFile 加载自定义程序集,这些文件已经加载到内存中。这会创建实体框架不喜欢的重复类。

于 2017-12-21T21:02:10.763 回答
0

我认为你在实体模型中有一个名为“MyClass”的类 X,在同一个 WorkFolder 或第一个类的扩展中有另一个名为“MyClass”的类。那是我的问题,我解决了。

于 2019-02-01T12:53:29.747 回答
0

如果您在 Web 配置中有 2 个连接字符串,但您想使用一个连接字符串您使用动态创建连接字符串其他实体。我的解决方案中有 edmx(db first) 和 code first Entities。我在 Code first 实体中使用这个类。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Data
{
    public class SingleConnection
    {
        private SingleConnection() { }
        private static SingleConnection _ConsString = null;
        private String _String = null;

        public static string ConString
        {
            get
            {
                if (_ConsString == null)
                {
                    _ConsString = new SingleConnection { _String = SingleConnection.Connect() };
                    return _ConsString._String;
                }
                else
                    return _ConsString._String;
            }
        }

        public static string Connect()
        {
            string conString = ConfigurationManager.ConnectionStrings["YourConnectionStringsName"].ConnectionString;

            if (conString.ToLower().StartsWith("metadata="))
            {
                System.Data.Entity.Core.EntityClient.EntityConnectionStringBuilder efBuilder = new System.Data.Entity.Core.EntityClient.EntityConnectionStringBuilder(conString);
                conString = efBuilder.ProviderConnectionString;
            }

            SqlConnectionStringBuilder cns = new SqlConnectionStringBuilder(conString);
            string dataSource = cns.DataSource;
            SqlConnectionStringBuilder sqlString = new SqlConnectionStringBuilder()
            {
                DataSource = cns.DataSource, // Server name
                InitialCatalog = cns.InitialCatalog,  //Database
                UserID = cns.UserID,         //Username
                Password = cns.Password,  //Password,
                MultipleActiveResultSets = true,
                ApplicationName = "EntityFramework",

            };
            //Build an Entity Framework connection string
            EntityConnectionStringBuilder entityString = new EntityConnectionStringBuilder()
            {
                Provider = "System.Data.SqlClient",
                Metadata = "res://*",
                ProviderConnectionString = sqlString.ToString()
            };
            return entityString.ConnectionString;
        }
    }
}

当我调用实体时

private static DBEntities context
{
get
{
    if (_context == null)
        _context = new DBEntities(SingleConnection.ConString);

    return _context;

}
set { _context = value; }
}
于 2018-12-13T09:54:40.440 回答
0

对我来说,这是因为我试图在错误的上下文实例上访问具有相同名称的类型。

两者ContextA兼有。ContextB_ SomeType我试图ContextA.SomeType访问ContextB.

于 2018-05-13T17:19:46.903 回答
0

我发现使用自定义注释解决方案适用于 EF 6.2.0。只需确保在 ConceptualModels 节点中进行更改并为该类型使用完整的命名空间。

<edmx:ConceptualModels>
  <Schema Namespace="Sample.Access.Data.Ef" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
    <EntityType Name="DbTableName" customannotation:ClrType="Sample.Access.Data.Ef.DbTableName, Sample.Access.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
      <Key>
        <PropertyRef Name="DbTableNameId" />
      </Key>
      <Property Name="DbTableNameId" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
      <Property Name="OptionName" Type="String" MaxLength="100" FixedLength="false" Unicode="false" Nullable="false" />
      <Property Name="Value" Type="String" MaxLength="500" FixedLength="false" Unicode="false" Nullable="false" />
      <Property Name="UpdatedDate" Type="DateTime" Nullable="false" Precision="3" />
    </EntityType>
    <EntityContainer Name="MyEntities" annotation:LazyLoadingEnabled="true" customannotation:UseClrTypes="true">
      <EntitySet Name="DbTableNames" EntityType="Self.DbTableName" />
    </EntityContainer>
  </Schema>
</edmx:ConceptualModels>
于 2021-08-10T15:58:09.987 回答
0

只需将 EntityFramework 添加为“数据库中的代码优先”而不是“数据库中的 EF 设计器”。这解决了我的问题,但它有一个黑暗的一面,如果您更改数据库,则必须删除所有类并再次添加它,或者只是编辑类,我在更改列的属性时使用最后一个,例如“允许null" 或字符串的大小。但是,如果您添加列,我建议您删除并再次添加这些类。

于 2018-08-13T16:53:37.407 回答
0

我能够在不重命名类、属性或元数据的情况下解决此问题。

我的项目设置是在 DAL 项目中创建实体对象的 T4 转换,以及在域项目中创建域对象的 T4 转换,两者都引用 EDMX 以生成相同的对象,然后我将 DAL 对象映射到域对象.

仅当我在查询中从域程序集中引用其他类(在我的情况下为枚举)时才会发生错误。当我删除它们时,错误就消失了。看起来 EF 正因此加载我的域程序集,看到其他同名的类,然后炸毁了。

为了解决这个问题,我制作了一个单独的程序集,其中仅包含我的 T4 转换后的域类。由于我从不需要在查询中使用这些(仅在要映射到的查询之后),我不再有这个问题。这似乎比下面的答案更干净、更容易。

于 2018-10-02T17:29:47.807 回答
-9

您可以下载一个名为 AutoMapper 的库。它可以帮助您定义从一种类型到另一种类型的类映射。

Mapper.CreateMap<Model.FileHistoryEFModel, DataTypes.FileHistory>();
Mapper.CreateMap<DataTypes.FileHistory, Model.FileHistoryEFModel>();
于 2015-02-09T12:07:58.007 回答