2009-07-06 19 views
3

私は、SQL Compact Edition上にEntity Frameworkを使用してアプリケーションを構築しています。私はビジネスオブジェクトとしてEntitesを使用するというアイデアが気に入らなかったので、私はそのレイヤーを構築していました(私はそれをObjectModelレイヤーと呼んでいます、最善の用語ではない)。エンティティを設定して保存します。そしてまた、その逆 - の私は、顧客と呼ばれるPOCOオブジェクトを持っているコードを避けるためのヒントこの抽象化の重複?

public class Customer:ICustomer 
    { 


     #region ICustomer Members 

     public System.Guid id {get;set;} 


     public string Forename {get;set;} 


     public string Surname { get; set; } 


     #endregion 
    } 

そして、私は私のObjectModel層を使用して、これを移入したいとしましょうビジネス・オブジェクトとして使用するためPOCOSを移入、


をentitesを取ります。 I現在、この...

OM_Customer<ICustomer,Entity.Customer> customerLayer = new OM_Agent<ICustomer,Entity.Customer>(); 

ICustomer businessObject = customerLayer.GetById(new Guid("4a75d5a5-6f5a-464f-b4b3-e7807806f1a9")); 

OM_Customerクラスは以下の通りですObjectModelBase、から継承します。..

public abstract class ObjectModelBase<BllClass, EntityClass> 
{ 
    public DataStoreEntities1 db; 

    public EntityClass _dataObject; 

    public string setName; 


    #region POCO-ORM Mapping Functions 
    public EntityClass MapBLLToEntity(BllClass bllObject) 
    { 
     Mapper.CreateMap<BllClass, EntityClass>(); 
     return Mapper.Map<BllClass, EntityClass>(bllObject); 
    } 

    public BllClass MapEntityToBLL(EntityClass entityObject) 
    { 
     Mapper.CreateMap<EntityClass, BllClass>(); 
     return Mapper.Map<EntityClass, BllClass>(entityObject); 
    } 
    #endregion 

    public void Save(BllClass toAdd) 
    { 
     _dataObject = MapBLLToEntity(toAdd); 

     using (db = new DataStoreEntities1()) 
     { 
      db.AddObject(setName, _dataObject); 
      db.SaveChanges(); 
     } 
    } 

    public BllClass GetById(Guid id) 
    { 
     using (db = new DataStoreEntities1()) 
     { 
      EntityClass result = (EntityClass)((object)(from c in db.CustomerSet where c.id == id select c).First()); 
      return MapEntityToBLL(result); 
     } 

    } 

} 

ここでの問題は、GetById方法です。 Saveメソッドは、すべてのEntity Framework Object ContextにAddObject()メソッドがあるため、サブクラスで使用できます。

すべての私のエンティティがidという性質を持っていますしかし、私は

...【選択問題がここにLINQということである(デシベルでも、主キーである)、ジェネリックgetByIdメソッドを持つことを望みます
ModelClass result = (ModelClass)((object)(from c in db.CustomerSet where c.id == id select c).First()); 

は、db.CustomerSetに固有です。私は、この抽象クラスで、すべてのエンティティに対して汎用のCRUD /ページング/ 'コレクションの取得'を提供したいと思いますが、繰り返しのキーストロークはありませんが、この簡単なGetByIdメソッドは私に助けを求めました。

現在のアイデア:

  • iは、クエリ文字列を構築するより細かく制御する必要があると思いますIdを使用するエンティティSQLによって私の取得を持っています。
  • 完全に抽象化するには時間がかかる可能性があるため、エンティティフレームワークとlinqを削除します。

SOコミュニティが上記を解決する方法についてのご意見をお待ちしております。

+0

WebアプリケーションまたはWindowsアプリケーションを構築していますか? –

+0

これはWindowsアプリケーションですが、Webアプリケーション、関連性のコードと同じように簡単にできますか? – RekrowYnapmoc

答えて

4

まず、ビジネスエンティティとしてEFエンティティを使用することが必然的に悪いと感じる理由を質問することから始めます。私はいくつかのプロジェクトでそうしてきましたが、私はまだ克服できない深刻な問題にぶつかっていません。

あなたは本当にあなたが2つを分離する強い理由があると感じたら、ここに1つのオプションがあります。

デリゲートを使用して、照会する特定のエンティティセットオブジェクトを挿入し、キーのセレクタに別のエンティティセットオブジェクトを注入することができます。デリバティブがストレージセマンティクスのみを指定できるようにすることができます。したがって、コードは次のようになります。

public abstract class ObjectModelBase<BllClass, EntityClass> 
{ 
    // ... same basic code here... 

    // supplied by your derivatives... 
    protected abstract Func<IQueryable<EntityClass>> GetEntitySet { get; }; 
    protected abstract Func<Guid,Func<EntityClass,bool>> KeySelector { get; } 

    public BllClass GetById(Guid id) 
    { 
     using (db = new DataStoreEntities1()) 
     { 
      EntityClass result = (EntityClass)((object) 
       GetEntitySet() 
        .Where(KeySelector(id)) 
        .First(); 
      return MapEntityToBLL(result); 
     } 
    } 
} 

public class OM_Customer : ObjectModelBase<ICustomer,Entity.Customer> 
{ 
    protected abstract Func<IQueryable<Entity.Customer>> GetEntitySet 
    { 
     get { return db.CustomerSet; } 
    } 

    protected abstract Func<Guid,Func<Entity.Customer,bool>> KeySelector 
    { 
     get { return (g => (e => e.Id == g)); } 
    } 
} 
+0

ありがとうございました。私は2つの理由から2つを分離する必要があると感じています。a)テスト容易性を促進するb)ビジネス・ロジック・クラスに触れることなく、将来的にデータ・アクセス・ソリューションを変更してください。 もう一度手伝ってくれてうれしいです。 – RekrowYnapmoc

関連する問題