2010-12-28 17 views
1

作業単位パターンに従ってインターフェイスを作成しています。私のインターフェースは次のようになります:作業単位とEF

public interface IDataContext : IDisposable 
{ 
    void SaveChanges(); 
    TSource Create<TSource>(TSource toCreate) where TSource : class; 
    TSource Update<TSource>(TSource toUpdate) where TSource : class; 
    bool Delete<TSource>(TSource toDelete) where TSource : class; 
    IQueryable<TSource> Query<TSource>(); 
} 

これまでのところとても良いです。今私は、データプロバイダとしてEF4を使用するデータレイヤーに実装します。私は "クエリ"メソッドのためのこのコードを思いついたが、それは非常にきれいではないと思う、私はそれを行う巧妙な方法があると感じるが、私は本当に把握することはできません。

public IQueryable<TSource> Query<TSource>() 
    { 
     var type = typeof(TSource); 
     IQueryable item = null; 

     if (type == typeof(Activity)) item = _entities.ActivitySet; 
     if (type == typeof(Company)) item = _entities.CompanySet; 
     if (type == typeof(Phase)) item = _entities.PhasesSet; 
     if (type == typeof(Project)) item = _entities.ProjectSet; 
     if (type == typeof(ProjectState)) item = _entities.ProjectStateSet; 
     if (type == typeof(ProjectType)) item = _entities.ProjectTypeSet; 
     if (type == typeof(User)) item = _entities.UserSet; 
     if (type == typeof(UserType)) item = _entities.UserTypeSet; 
     if (item != null) return item as IQueryable<TSource>; 

     throw new NotImplementedException(string.Format("Query not implemented for type {0}", type.FullName)); 
    } 

私はここを参照してください問題は、まだ私にはかなりひどい見える場合は、他のすべてのIFSは、カスケードで、私はそれらをチェーンできalthoughtをするたびに検査を受けるです。他の問題は、追加される可能性のある新しいエンティティごとに手動で1行追加する必要があることですが、それは私の主な関心事ではありません。

誰もがこれに関する良いアドバイスをしていますか?ありがとう。

+0

「_entities」とは何ですか?あなたは '_entities.GetEntity ()'のようなものに変更できるかもしれませんが、それは何であるかによって異なります。 – SwDevMan81

+0

_entitiesは、Entity Frameworkの自動生成クラスです。 –

答えて

1

EF4を使用している場合は、CreateObjectSet <>を呼び出すことができます。

using System; 
using System.Collections.Generic; 
using System.Data.Objects; 
using System.Linq; 

namespace WindowsFormsApplication1 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      var context = new DataContext(new NorthwindEntities()); 
      var list = context.Query<Customer>().ToList(); 
      var list2 = context.Query<Customer>().ToList(); 
     } 
    } 

    public class DataContext : IDataContext 
    { 
     private Dictionary<Type, object> _objectSets = new Dictionary<Type,object>(); 
     private ObjectContext _entities; 

     public DataContext(ObjectContext objectContext) 
     { 
      this._entities = objectContext; 
     } 

     public IQueryable<T> Query<T>() 
      where T : class 
     { 
      Type entityType = typeof(T); 
      ObjectSet<T> objectSet; 

      if (this._objectSets.ContainsKey(entityType)) 
      { 
       objectSet = this._objectSets[entityType] as ObjectSet<T>; 
      } 
      else 
      { 
       objectSet = this._entities.CreateObjectSet<T>(); 
       this._objectSets.Add(entityType, objectSet); 
      } 

      return objectSet; 
     } 
    } 

    interface IDataContext 
    { 
     IQueryable<T> Query<T>() where T : class; 
    } 
} 

あなたはEF1を使用している場合は、からCreateQuery <を呼び出すことができます>あなたはまた、エンティティ セット名を見つける必要があります。

using System; 
using System.Collections.Generic; 
using System.Data.Metadata.Edm; 
using System.Data.Objects; 
using System.Linq; 

namespace WindowsFormsApplication2 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      var context = new DataContext(new NorthwindEntities()); 
      var list = context.Query<Customer>().ToList(); 
     } 
    } 

    public class DataContext : IDataContext 
    { 
     private Dictionary<string, string> _entitySets; 
     private ObjectContext _entities; 

     public DataContext(ObjectContext objectContext) 
     { 
      this._entities = objectContext; 
     } 

     public IQueryable<T> Query<T>() 
      where T : class 
     { 
      return this._entities.CreateQuery<T>(this.GetEntitySetName<T>()); 
     } 

     private string GetEntitySetName<T>() 
      where T : class 
     { 
      if (this._entitySets == null) 
      { 
       // create a dictionary of the Entity Type/EntitySet Name 
       this._entitySets = this._entities.MetadataWorkspace 
               .GetItems<EntityContainer>(DataSpace.CSpace) 
               .First() 
               .BaseEntitySets.OfType<EntitySet>().ToList() 
               .ToDictionary(d => d.ElementType.Name, d => d.Name); 
      } 

      Type entityType = typeof(T); 

      // lookup the entity set name based on the entityType 
      return this._entitySets[entityType.Name]; 
     } 
    } 

    interface IDataContext 
    { 
     IQueryable<T> Query<T>() where T : class; 
    } 
} 
+0

私はEF4を使用していますが、クエリを実行するたびにオブジェクトセットを再作成したくありません。 –

+0

EF4の例を編集してObjectSetのキャッシュをインクルードしました。 –

0

一つの方法は、すべての定義済みObjectSetsで自動生成されたObjectContextを使用して、代わりに呼び出すことはありませすることができます。

public IQueryable<TSource> Query<TSource> 
{ 
    return _entities.CreateObjectSet<TSource>(); 
} 

しかし、私は影響がクエリを実行するたびに、設定オブジェクトを作成しているものの性能はよく分かりません。私は通常、オブジェクトセットのいくつかの怠惰な初期化(すでに作成されたオブジェクトセットを格納するための辞書を使用)を行い、それらを単一の作業単位インスタンスのために再利用しています。

+0

それはまさにそれがどのように動作するのか、それは私が保存しようとしている動作です。結局それを行うクリーナーモードがないかもしれない。 CreateObjectSetを毎回呼び出すことなく、少なくとも。 –

関連する問題