2

私はエンティティ フレームワーク 4 を使用しており、多くのテーブル (500) があります。私の edmx ファイルは非常に大きく、それを開いて変更するのは非常に困難です。私のプロジェクトには、特定のビジネスに関連するテーブルの「グループ」があることがわかったので、edmx をいくつかのファイルに分けたいと思います。私はリポジトリパターンと作業単位パターンを使用しており、POCO を次のように操作しています。

This is my container
    public partial class MyEntities : ObjectContext {
        #region Private Methods
        private void SetContextOptions() {
            ContextOptions.LazyLoadingEnabled = false;
        }
        #endregion

        #region Constructors
        public MyEntities()
            : base("name=MyConnection", "MyEntities") {
            SetContextOptions();
            OnContextCreated();
        }
        #endregion

        #region Partial Methods
        partial void OnContextCreated();
        #endregion
    }

各 edmx について、Entity Container Name プロパティを MyEntities に設定します。これは私の一般的なリポジトリです:

public class Repository<T> : IRepository<T> where T : class, IDataEntity
{
    ObjectContext _context;
    IObjectSet<T> _objectSet;

    protected ObjectContext Context
    {
        get
        {
            if (_context == null)
            {
                _context = GetCurrentUnitOfWork<EFUnitOfWork>().Context;
            }

            return _context;
        }
    }

    protected IObjectSet<T> ObjectSet
    {
        get
        {
            if (_objectSet == null)
            {
                _objectSet = this.Context.CreateObjectSet<T>();
            }

            return _objectSet;
        }
    }

    public TUnitOfWork GetCurrentUnitOfWork<TUnitOfWork>() where TUnitOfWork : IUnitOfWork
    {
        return (TUnitOfWork)UnitOfWork.Current;
    }       

    public virtual IQueryable<T> GetQuery(IEnumerable<Expression<Func<T, object>>> includes)
    {
        return ObjectSet.IncludeMultiple(includes);
    }

    public virtual IPaged<T> GetQuery(IQueryable<T> query,
        Func<IQueryable<T>, IOrderedQueryable<T>> orderBy, int pageNumber, int pageSize)
    {
        if (orderBy != null)
        {
            query = orderBy(query);
        }

        IPaged<T> page = new Paged<T>(query, pageNumber, pageSize);

        return page;
    }

    public virtual IPaged<T> GetQuery(IEnumerable<T> query,
        Func<IEnumerable<T>, IOrderedEnumerable<T>> orderBy, int pageNumber, int pageSize)
    {
        if (orderBy != null)
        {
            query = orderBy(query);
        }

        IPaged<T> page = new Paged<T>(query, pageNumber, pageSize);

        return page;
    }

    public virtual IEnumerable<T> GetObjectStateManagerChanges()
    {
        return this.Context.ObjectStateManager.
            GetObjectStateEntries(EntityState.Added | EntityState.Modified).
            Select(e => e.Entity).
            OfType<T>();
    }

    public virtual void Insert(T entity)
    {
        this.ObjectSet.AddObject(entity);
    }

    public virtual void Delete(T entity)
    {
        this.ObjectSet.DeleteObject(entity);
    }

    public virtual void MarkModified(T entity)
    {
        this.Context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
    }

    public virtual void Attach(T entity)
    {
        ObjectStateEntry entry = null;
        if (this.Context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry) == false)
        {
            this.ObjectSet.Attach(entity);
        }
    }

    public virtual void Detach(T entity)
    {
        ObjectStateEntry entry = null;
        if (this.Context.ObjectStateManager.TryGetObjectStateEntry(entity, out entry) == true)
        {
            this.ObjectSet.Detach(entity);
        }
    }

    public virtual T GetOriginalEntity(Func<T, bool> predicate)
    {
        T originalEntity = null;
        EFUnitOfWorkFactory factory = new EFUnitOfWorkFactory();
        using (EFUnitOfWork uow = (EFUnitOfWork)factory.Create())
        {
            originalEntity = uow.Context.CreateObjectSet<T>().Single(predicate);
        }
        return originalEntity;
    }
}

そして、これは私の作業単位の実装です:

    public class EFUnitOfWorkFactory : IUnitOfWorkFactory
    {
        private static int Counter = 0;
        private static Func<ObjectContext> _objectContextDelegate;
        private static readonly Object _lockObject = new object();

        public static void SetObjectContext(Func<ObjectContext> objectContextDelegate)
        {
            _objectContextDelegate = objectContextDelegate;
        }

        public IUnitOfWork Create()
        {
            ObjectContext context;

            lock (_lockObject)
            {
                Counter++;
                context = _objectContextDelegate();
            }

            return new EFUnitOfWork(context, Counter);
        }
    }

public class EFUnitOfWork : IUnitOfWork, IDisposable
    {
        public ObjectContext Context { get; private set; }
        public int Id { get; private set; }

        public EFUnitOfWork(ObjectContext context, int id)
        {
            Id = id;
            Context = context;
            Context.ContextOptions.LazyLoadingEnabled = false;
        }

        public int Commit()
        {
            return Context.SaveChanges();
        }

        public void Dispose()
        {
            if (Context != null)
            {
                Context.Dispose();
                Context = null;
            }

            GC.SuppressFinalize(this);
        }
    }

私の計画は、このコードで edmx の作業を分割するように機能しますか? 私の場合のベスト プラクティスは何ですか ( http://blogs.msdn.com/b/adonet/archive/2008/11/24/working-with-large-models-in-entity-の 2 つの部分を読みました)。フレームワーク-パート-1.aspx )?

編集: edmxs のエンティティ コンテナー名を MyEntities に設定しようとすると、次のようになります。

EntityContainer name 'MyEntities' is already in use by another Entity Data Model in the project.

回避策はありますか?

4

1 に答える 1

0

ナオール、

このエンティティの poco クラスを生成する必要があります。これにより、作成したエンティティで右クリックするための pococlasses が自動的に作成されます。E4 entitypocogenrator を選択する必要があるという点で、コード ジェネレーターをクリックするとそのオプションが表示され、オブジェクト コンテキストが自動的に作成されます。そして pococlass これらのクラスは、必要なものを分離する必要がある部分クラスです。E4enitypocogenrater が見つからない場合は、これをインストールする必要があります。Ado.entity フレームワーク http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313/で poco クラスをインストールするためのリンクです。

于 2012-07-18T11:45:34.797 に答える