Generic Unit Of Work

六月ゝ 毕业季﹏ 提交于 2021-02-07 09:26:33

问题


I have implemented EntityFramework pattern along with Repository and Unit Of Work. The implementation is similar to Code Project Repository Example, however I need an enhancement for the Unit Of Work.

The unit of work

public class GenericUnitOfWork : IDisposable
{
    // Initialization code

    public Dictionary<Type, object> repositories = new Dictionary<Type, object>();

    public IRepository<T> Repository<T>() where T : class
    {
        if (repositories.Keys.Contains(typeof(T)) == true)
        {
            return repositories[typeof(T)] as IRepository<T>
        }
        IRepository<T> repo = new Repository<T>(entities);
        repositories.Add(typeof(T), repo);
        return repo;
    }

    // other methods
}

The above UoW is quiet generalized and it targets the parent Repository class always. I have another entity, for example student, which has its own repository extending the Repository class. The student specific repository has a method "GetStudentMarks()". Now I cannot use the general Unit Of Work class since it always points to the parent Repository.

How to implement a general Unit Of Work to handle such situations? Thanks in advance.


回答1:


You can make the class GenericUnitOfWork generics, specifying the entity and repository type:

public class GenericUnitOfWork<TRepo, TEntity> : IDisposable
    where TRepo : Repository<TEntity>
{
    // Initialization code

    public Dictionary<Type, TRepo> repositories = new Dictionary<Type, TRepo>();

    public TRepo Repository()
    {
        if (repositories.Keys.Contains(typeof(TEntity)) == true)
        {
            return repositories[typeof(TEntity)];
        }
        TRepo repo = (TRepo)Activator.CreateInstance(
            typeof(TRepo),
            new object[] { /*put there parameters to pass*/ });
        repositories.Add(typeof(TEntity), repo);
        return repo;
    }

    // other methods
}

Something like this should works.




回答2:


Generic UnitOfWork !!! You've implemented the wrong unit of work

See This Code:

using System.Data.Entity;
using System;


namespace EF_Sample07.DataLayer.Context
{
 public interface IUnitOfWork
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
   }
 }

Why Use UnitOfWork?

Because:

  • Better performance
  • Concurrency issues
  • The correct use of transactions

See Example :

Category

   public class Category
{
    public int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Title { get; set; }


    public virtual ICollection<Product> Products { get; set; }
}

Product

    public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }


    [ForeignKey("CategoryId")]
    public virtual Category Category { get; set; }
    public int CategoryId { get; set; }
}

UnitOfWork

  public interface IUnitOfWork
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
}

DbContext

    public class Sample07Context : DbContext, IUnitOfWork
{
    public DbSet<Category> Categories { set; get; }
    public DbSet<Product> Products { set; get; }


    #region IUnitOfWork Members
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        return base.Set<TEntity>();
    }
    public int SaveAllChanges()
    {
        return base.SaveChanges();
    }
    #endregion
}



回答3:


I suppose that, you want to perform some operations over StudentMarks in GetStudentMarks method. Otherwise if your models are correctly mapped, you can just load them using one of the relation data loading methods. Otherwise, if general Repository suits most of your entities, but you need some additional methods for a little number of your entities, then I recommend creating extension methods for these repositories:

public static class StudentReposityExtensions
{
    public List<Mark> GetStudentMarks(
        this IRepository<Student> studentRepostitory)
    {
        .....
    }
}


来源:https://stackoverflow.com/questions/39343750/generic-unit-of-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!