How can I implement CRUD operations in a base class for an entity infrastructure application?

I am working with a simple EF / MVC application and I am trying to implement some repositories to process my objects. I configured the BaseObject class and the IBaseRepository interface to handle the most basic operations, so I don’t need to repeat each time:

public abstract class BaseObject<T>
    {
        public XA.Model.Entities.XAEntities db;
        public BaseObject()
        {
            db = new Entities.XAEntities();
        }

        public BaseObject(Entities.XAEntities cont)
        {
            db = cont;
        }

        public void Delete(T entity)
        {
            db.DeleteObject(entity);
            db.SaveChanges();
        }

        public void Update(T entity)
        {
            db.AcceptAllChanges();
            db.SaveChanges();
        }
   }

    public interface IBaseRepository<T>
    {
        void Add(T entity);

        T GetById(int id);
        IQueryable<T> GetAll();
    }

But then I discovered that I need to implement 3 main methods in each repository (Add, GetById and GetAll):

public class AgencyRepository : Framework.BaseObject<Agency>, Framework.IBaseRepository<Agency>
    {
        public void Add(Agency entity)
        {
            db.Companies.AddObject(entity);
            db.SaveChanges();
        }
        public Agency GetById(int id)
        {
            return db.Companies.OfType<Agency>().FirstOrDefault(x => x.Id == id);
        }
        public IQueryable<Agency> GetAll()
        {
            var agn = from a in db.Companies.OfType<Agency>()
                      select a;
            return agn;
        }
    }

How can I get them in my BaseObject class, so I won’t work in conflict with DRY.

+3
source share
4 answers

Hi, I ran into the same problem. Go for a solution like this

namespace ABC
{
    public class EntitiesRepository<T> : IDisposable where T : class
    {
        private ObjectContext _context;

        /// <summary>
        /// The IObjectSet that represents the current entity.
        /// </summary>
        private ObjectSet<T> _objectSet;

        public OperationStatus status { get; set; }

        /// <summary>
        /// Initializes a new instance of the DataRepository class
        /// </summary>
        public BilderQuizEntitiesRepository()
        {
            _context = new Entities();  //DBContext

            _objectSet = _context.CreateObjectSet<T>();
         }

        public T Select(int id)
        {
            EntityKey key = GetEntityKey(id);

            return (T)_context.GetObjectByKey(key);
        }

        public void Delete(T entity)
        {
            try
            {
                if (entity == null)
                {

                    throw new ArgumentNullException("entity");
                }

                EntityKey key = GetEntitySpecificKey(entity);
                T attachEntity = (T)_context.GetObjectByKey(key);
                _objectSet.DeleteObject(attachEntity);
                SaveChanges();                
            }
            catch
            {

            }

        }       

        public void Delete(int id)
        {
            EntityKey key = GetEntityKey(id);
            Delete((T)_context.GetObjectByKey(key));
            SaveChanges();
        }

        public void Update(T entity)
        {
            try
            {
                if (entity == null)
                {

                    throw new ArgumentNullException("entity");
                }

                EntityKey key = GetEntitySpecificKey(entity);
                T attachEntity = (T)_context.GetObjectByKey(key);
                _objectSet.Attach(attachEntity);
                _objectSet.ApplyCurrentValues(entity);
                SaveChanges();

            }
            catch
            {

            }

        }       

        /// <summary>
        /// Returns Entity Key 
        /// </summary>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        private EntityKey GetEntityKey(object keyValue) //Get EnrityKey
        {
            var entitySetName = _context.DefaultContainerName + "." + _objectSet.EntitySet.Name;
            var keyPropertyName = _objectSet.EntitySet.ElementType.KeyMembers[0].ToString();
            var entityKey = new EntityKey(entitySetName, new[] { new EntityKeyMember(keyPropertyName, keyValue) });
            return entityKey;
        }

        /// <summary>
        /// Returns Entity Key 
        /// </summary>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        private EntityKey GetEntitySpecificKey(T entity) //Get EnrityKey
        {
            Type objType = typeof(T);
            var keyPropertyName = _objectSet.EntitySet.ElementType.KeyMembers[0].ToString();
            var pi = objType.GetProperty(keyPropertyName);
            var keyValue = pi.GetValue(entity, null);
            var entitySetName = _context.DefaultContainerName + "." + _objectSet.EntitySet.Name;

            var entityKey = new EntityKey(entitySetName, new[] { new EntityKeyMember(keyPropertyName, keyValue) });
            return entityKey;
        }

        private string GetPrimaryKeyValue(T entity)
        {
            Type objType = typeof(T);
            var keyPropertyName = _objectSet.EntitySet.ElementType.KeyMembers[0].ToString();
            var pi = objType.GetProperty(keyPropertyName);
            var keyValue = pi.GetValue(entity, null);
            return keyValue.ToString();
        }

        /// <summary>
        /// Saves all context changes
        /// </summary>
        public bool SaveChanges()
        {
            return _context.SaveChanges() > 0 ? true : false;
        }

        /// <summary>
        /// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
        /// </summary>
        public void Dispose()
        {

            Dispose(true);

            GC.SuppressFinalize(this);

        }

        /// <summary>
        /// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
        /// </summary>
        /// <param name="disposing">A boolean value indicating whether or not to dispose managed resources</param>
        protected virtual void Dispose(bool disposing)
        {

            if (disposing)
            {

                if (_context != null)
                {

                    _context.Dispose();

                    _context = null;

                }

            }

        }
    }

}

, ,

+1

( ), . , , .

, db , , , , . unit test, - , .

0

T4 EF 4. T4 EF 1.

, . MyEntity.Update() . EF (, ). , - , . IMHO EF. .

0

, , , , -. - abstrat , , select, insert, update delete.

:

public abstract class MyContext<T, key> : IDisposable where T : class {

    private DbEntities db;    //my database context
    private DbSet<T> entities;  //specific set

    protected MyContext(DbEntities db) {
        entities = db.Set<T>();
        this.db = db;
    }

    public T Add(T entity) {
        entities.Add(entity);
        db.SaveChanges();
        return entity;
    }

    public T Get(key id) {
        return entities.Find(id);
    }

    public List<T> GetAll() {
        return entities.ToList();
    }

    public void Delete(key id) { 
        T objectToDelete=entities.Find(id);
        if(objectToDelete!=null){
            entities.Remove(objectToDelete);
            db.SaveChanges();
        }  
    }

    public void Delete(T entity) {
        entities.Remove(entity);
        db.SaveChanges();
    }

    public void Delete(List<T> items) {
        foreach (T entity in items) {
            entities.Remove(entity);
        }
        db.SaveChanges();
    }

    public void Update(T entity) {
        entities.Attach(entity);
        db.Entry(entity).State = EntityState.Modified;
        db.SaveChanges();
    }

    public abstract void Dispose();
}

public class PermissionDataBase : MyContext<Permission,int>{  
    //Mapped class Permission where the key is int

    private DbEntities db=null;

    public PermissionDataBase(DbEntities db):base(db) {
        this.db = db;
    }

    //Additional methods (if required)
    public Permission FindByName(string name) {
        return db.Permissions.FirstOrDefault(p => p.Name == name);
    }

    public override void Dispose() {
        db.Dispose();
    }
}

public class ModelsTest {
    [TestMethod]
    public void TestMethod1() {
        DbEntities db = new DbEntities();
        using (PermissionDataBase permissionDb = new PermissionDataBase(db)) {

            Permission newEntity = new Permission() {
                Name = "Test1"
            };

            permissionDb.Add(newEntity);

            Assert.IsTrue(newEntity.Id > 0);
        }
    }

    [TestMethod]
    public void TestMethod2() {
        DbEntities db = new DbEntities();
        using (PermissionDataBase permissionDb = new PermissionDataBase(db)) {

            List<Permission> items = permissionDb.GetAll();
            Assert.IsTrue(items.Count > 0);
        }
    }

    [TestMethod]
    public void TestMethod3() {
        DbEntities db = new DbEntities();
        using (PermissionDataBase permissionDb = new PermissionDataBase(db)) {

            Permission toDelete = permissionDb.Get(3);  //Assuming id=3 exists
            permissionDb.Delete(toDelete);

            Permission deleted = permissionDb.Get(3);
            Assert.IsNull(deleted);
        }
    }
}

Entity Framework 5 Visual Studio Community 2013.

0

Source: https://habr.com/ru/post/1746079/


All Articles