web-dev-qa-db-ja.com

CLRタイプからEDMタイプへのマッピングは、EF 6および5では曖昧ですか?

このエラーを修正するために誰か助けてください。

指定されたスキーマは無効です。エラー:

複数のCLRタイプがEDMタイプ「City_DAL」と一致するため、CLRタイプからEDMタイプへのマッピングはあいまいです。以前に見つかったCLRタイプ「CeossDAL.City_DAL」、新しく見つかったCLRタイプ「CeossBLL.City_DAL」。

私がDALを持っている主な問題は、これにはEFとBLLが含まれ、これにはDALの同じクラスが含まれていますが、名前空間が異なり、これが問題の原因です

これらの問題を取り除く方法がわかりません。助けてください。

また、EFでn層アーキテクチャを使用するためのサンプルを提供してくれる人がいれば幸いです

ありがとうございました

66
Mahmoud Samir

同じ名前のクラスを使用しないでください非修飾 name-EFはクラス名のみを使用してEDMXにマッピングされたタイプを識別します(名前空間は無視されます)-異なる名前空間から単一モデルへのクラスのマッピングを許可する規則です。問題の解決策は、BLLのクラスに異なる名前を付けることです。

76
Ladislav Mrnka

回避策:2つの同一のクラスのいずれかのプロパティを変更します。

EFは、クラス名とクラスプロパティで一致します。したがって、EFオブジェクトの1つのプロパティ名を変更しただけで、エラーはなくなりました。

@Entrodusが他の回答の1つにコメントしたように:

EFコリジョンは、2つのクラスが同じ名前と同じパラメーターセットを持っている場合にのみ発生します。

38
Matt

これ MSDNフォーラムの質問は役に立つかもしれません。 BLLクラスとDALクラスを別々のアセンブリに配置することをお勧めします。

10
Jarno

EF 6.xの場合、 https://github.com/aspnet/EntityFramework/issues/941 でいくつかのメモを見つけ、EDMタイプに注釈を追加することでこれを修正しました。

EDMXファイルを手動で編集し、次のように行を変更しました:

<EntityType Name="CartItem">

これに:

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

or他の場所に既存のタイプがある場合、これを使用します。

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

ここで、EntityModelはEFモデルに使用される名前空間であり、MyAppはビジネスオブジェクトの名前空間です

7
Ekus

場合によっては、これは実際の問題よりも症状です。私にとっては、通常、最初に.ToList()を呼び出さずにLinqクエリ内の関数を呼び出そうとするとポップアップします。

例えば。私がここに来たエラーは、私がこれをしたために発生しました:

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()を呼び出してから、各項目を繰り返し処理して、型を割り当てる必要がありました。

5

これは質問をしたときに利用できなかったかもしれませんが、別の解決策はEDMXを削除し、コード優先エンティティデータモデルとして再作成することです。 EF6では、コードファーストにより、競合を発生させることなく、異なるモデル名前空間から同じ名前の2つのクラスをマップできます。

Visual Studio(2013)でエンティティデータモデルを作成するには、[追加]> [新しいアイテム...]> [ADO.NETエンティティデータモデル]に移動します。必ず「データベースから最初にコードを作成」オプションを選択してください。

1
Tawab Wakil

エンティティモデルに「MyClass」という名前のクラスXと、最初のクラスの同じWorkFolderまたはExtendedに「MyClass」と呼ばれる別のクラスがあると思います。それが私の問題であり、私はそれを修正します。

0

クラス、プロパティ、またはメタデータの名前を変更せずに、この問題を解決できました。

DALプロジェクトでエンティティオブジェクトを作成するT4トランスフォーム、およびドメインプロジェクトでドメインオブジェクトを作成するT4トランスフォームを使用してプロジェクトをセットアップし、どちらもEDMXを参照して同一のオブジェクトを生成し、DALオブジェクトをドメインオブジェクトにマッピングしていました。

このエラーは、クエリでドメインアセンブリから他のクラス(私の場合は列挙)を参照しているときにのみ発生しました。それらを削除すると、エラーはなくなりました。このため、EFがドメインアセンブリを読み込んでおり、他の同じ名前のクラスが表示され、爆発しているようです。

これを解決するために、T4変換済みドメインクラスのみを含む別のアセンブリを作成しました。クエリ内でこれらを使用する必要がないため(マップするクエリの後にのみ)、この問題は発生しなくなりました。これは、以下の回答よりも簡潔で簡単に思えます。

0
Carson

両方の接続文字列について、メインプロジェクトの設定ファイルで指定されているメタデータの値が次のようになっているため、上記のエラーが発生しました。

<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" />

EntitiesBのプロジェクトの設定ファイルから正しい接続文字列をコピーすることになりました。

0

私にとって、これは間違ったコンテキストインスタンスで同じ名前の型にアクセスしようとしたためでした。

ContextAContextBの両方にSomeTypeがあるとしましょう。アクセスしようとしていたContextA.SomeTypeContextBのインスタンス。

0
Dave Cousineau

web構成に2つの接続文字列があるが、1つの接続文字列を使用する場合、動的な接続文字列を作成する他のエンティティを使用します。私のソリューションでは、edmx(db first)とcode first Entitiesがあります。このクラスは、コードファーストエンティティで使用します。

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; }
}
0
Cetin Sahin

EntityFrameworkを「データベースからのEFデザイナー」としてではなく、「データベースからのコードファースト」として追加するだけです。これで問題が解決しましたが、データベースに変更を加えた場合、すべてのクラスを削除して再度追加するか、クラスを編集するだけで、列のプロパティを変更するときに最後のnull」または文字列のサイズ。ただし、列を追加する場合は、クラスを削除して再度追加することをお勧めします。

このエラーが発生する可能性がある別の理由:edmxファイルを含むAssembly.LoadFileを使用して、既にメモリにロードされているカスタムアセンブリをロードする場合。これにより、エンティティフレームワークが好ましくない重複クラスが作成されます。

0
Thomas