简体   繁体   English

实体框架-使用多个edmx文件

[英]entity framework - working with several edmx files

I am using entity framework 4 and I have many tables (500). 我正在使用实体框架4,并且有很多表(500)。 My edmx file is very large and I find it really hard to open it and make changes on it. 我的edmx文件很大,我发现很难打开它并对其进行更改。 I found that in my project there are "groups" of tables that related to specific business so I would like to saperate the edmx into several files. 我发现在我的项目中有与特定业务相关的表的“组”,因此我想将edmx分成几个文件。 I am using repository pattern and unit of work pattern and work with POCOs this way: 我正在使用存储库模式和工作单元模式,并以这种方式使用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
    }

For each edmx I will set the Entity Container Name property to MyEntities. 对于每个edmx,我将“实体容器名称”属性设置为MyEntities。 This is my generic repository: 这是我的通用存储库:

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;
    }
}

And this is my unit of work implementation: 这是我的工作单元实施:

    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);
        }
    }

will my plan work to divide the edmx work with this code? 我的计划将使用此代码划分edmx的工作吗? What is the best practices for my case (I have read the two parts of http://blogs.msdn.com/b/adonet/archive/2008/11/24/working-with-large-models-in-entity-framework-part-1.aspx )? 我的案例的最佳做法是什么(我已阅读http://blogs.msdn.com/b/adonet/archive/2008/11/24/working-with-large-models-in-entity- framework-part-1.aspx )?

EDIT: When trying to set the entity container names of the edmxs to MyEntities, I get: 编辑:尝试将edmxs的实体容器名称设置为MyEntities时,我得到:

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

Is there any workaround? 有什么解决方法吗?

Naor, 娜or

You need to Generate a poco Class for this entity it automatically create pococlasses for right click in entity which you have created ,you able to view options in that in that click on code generator in that you need to select E4 entitypocogenrator it automatically create object context and pococlass those classes are partial class we need to separate which we want. 您需要为此实体生成一个poco类,它会自动为您创建的实体右键单击创建pococlasss,您可以在其中单击代码生成器以查看选项,因为您需要选择E4实体pocogenrator它会自动创建对象上下文和pococlass这些类是我们需要分开的部分类。 if you are unable to find E4enitypocogenrater you need to install this one here is the link to instal the poco class fr Ado.entity frame work http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313/ 如果您找不到E4enitypocogenrater,则需要安装此工具,这里是安装poco类的链接,网址为Ado.entity框架http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM