6

私は、単一のビジネスロジッククラスを使用して、さまざまなエンティティフレームワーククラスで同様の操作を実行したいという状況があります。これらのクラスが部分クラスファイルで実装するインタフェースを定義しました。LINQ to Entities to Interface Property

ただし、これらのインターフェイスメソッドに対してエンティティクエリにLINQを書き込もうとすると、クエリでクラスのプロパティを直接使用せずインターフェイス経由で使用するため、NotSupportedExceptionが発生します。

LINQをオブジェクトに頼らずにこれを達成する方法があるので、データベース層を重くしたいと思いますか?

私の問題(工場で作成された汎用リポジトリクラスを使用しています)を示すコードです。

答えて

0
public interface INamedEntity 
{ 
    int ID { get; set; } 
    string Name { get; set; } 
} 

// This is an Entity Framework class which has CustomerID and CustomerName properties. 
public partial class Customer: INamedEntity 
{ 
    int INamedEntity.ID 
    { 
     get { return this.CustomerID; } 
     set { this.CustomerID = value; } 
    } 
    string INamedEntity.Name 
    { 
     get { return this.CustomerName; } 
     set { this.CustomerName = value; } 
    } 
} 

... 

public string GetName<T>(int entityID) where T: EntityObject, INamedEntity 
{ 
    using(var repository = RepositoryFactory.CreateRepository<T>()) 
    { 
     return repository 
      .Where(e => e.ID == entityID) 
      .Select(e.Name) 
      .Single(); 
    } 
} 

次の例外は、汎用ソース上とWHERE句で使用されるインターフェース部材とベースのクエリ実行中occures。

NotSupportedException:インターフェイスメンバ[InterfaceName]。[MemberName]のマッピングがサポートされていません。

例外が発生するのは、クエリで複数のアイテムが返され、==演算子が使用された場合のみです。 First、FirstOrDefaultまたはSingleのクエリを実行したとき、またはwhere句でequalsやその他の演算子を使用したときにエラーを再現できませんでした。

参考:これは、サポートされていませんInterface not supported

+0

はい、問題のようです。 – gareththegeek

5

。 Linqからエンティティへのクエリでは、エンティティのマップされたプロパティのみを使用できます。インターフェイスのプロパティを使用する場合、プロパティの実装でコードを解析できないため、EFはSQLへの変換方法がわかりません。

エンティティにインターフェイスを使用しない - EFではエンティティをまったくサポートしていません。あなたの特殊なケースでは、マッピングには不明なプロパティをクエリしているので、他のORMでも機能しません。これは、実際のマップされたプロパティでクエリに翻訳する独自のLinqプロバイダを構築する必要があります。

+0

しかし、この種のパターンを達成する方法はありますか?理想的には、各機能領域のビジネスロジックユニットがあり、インタフェースとすべての関連エンティティへのマッピングが行われます。 – gareththegeek

+1

しかし、それはあなたのビジネスロジックインターフェースプロパティを実際のEFプロパティに変換する、EFの上に別の "マッピング"レイヤーを意味します。このマッピングレイヤはクエリも変換します。私はこのパターンを呼んでいません - 私はそれを建築用アプリケーションの上に呼びます。 –

+0

おそらくオーバーアーキテクトされていますが、同じコードを複数のビジネスレイヤオブジェクトにコピーして貼り付けて、同じロジックを実行できますが、別の名前のエンティティプロパティを使用することは避けてください。 – gareththegeek