1

プロジェクトでは、ジェネリックリポジトリとジェネリックマネージャーを使用するため、すべてのリポジトリ/マネージャーですべての更新/削除などのメソッドを書き直す必要はありません。

外観は次のとおりです。

public interface IBaseRep<T> : IDisposable where T : class, PrivateObject
{
    DbSet<T> DatabaseSet { get; set; }
    DbContext Dal { get; set; }

    T Find(int? id);
    T Find(Expression<Func<T, bool>> predicate);
    ICollection<T> Select(Expression<Func<T, bool>> predicate = null,
        Expression<Func<T, string>> orderBy = null,
        string includeProperties = "");
    T Create(T obj);
    T Update(T obj);
    bool Delete(T obj);
    bool Delete(int id);
    bool Delete(Expression<Func<T, bool>> predicate);
    IQueryable<T> SelectAsQuery(
        Expression<Func<T, bool>> predicate = null, 
        Expression<Func<T, string>> orderBy = null, 
        string includeProperties = "");
}

public class BaseRep<T> : IBaseRep<T> where T : class, PrivateObject
{
    public DbSet<T> DatabaseSet { get; set; }
    public DbContext Dal { get; set; }

    public EORTCBaseRep(DbContext dal)
    {
        this.Dal = dal;
        this.DatabaseSet = Dal.Set<T>();
    }

    public virtual T Find(int? id)
    {
        return this.DatabaseSet.Find(id);
    }

    public virtual T Find(Expression<Func<T, bool>> predicate)
    {
        return Select(predicate).FirstOrDefault();
    }

    public virtual ICollection<T> Select(
        Expression<Func<T, bool>> predicate = null,
        Expression<Func<T, string>> orderBy = null,
        string includeProperties = "")
    {
        return SelectAsQuery(predicate, orderBy, includeProperties).ToList();
    }

    public virtual IQueryable<T> SelectAsQuery(
       Expression<Func<T, bool>> predicate = null,
       Expression<Func<T, string>> orderBy = null,
       string includeProperties = "")
    {
        IQueryable<T> query = this.DatabaseSet;

        if (predicate != null)
            query = query.Where(predicate);

        foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            query = query.Include(includeProperty);

        if (orderBy != null)
            query = query.OrderBy(orderBy);

        return query;
    }

    public virtual T Create(T obj)
    {
        this.Dal.Entry<T>(obj).State = EntityState.Added;
        this.Dal.SaveChanges();
        return obj;
    }

    public virtual T Update(T obj)
    {
        this.Dal.Entry<T>(obj).State = EntityState.Modified;
        this.Dal.SaveChanges();
        return obj;
    }

    public virtual bool Delete(T obj)
    {
        if (obj is ILogicallyDeletable)
        {
            this.Dal.Entry<T>(obj).State = EntityState.Modified;
            (obj as ILogicallyDeletable).IsDeleted = true;
        }
        else
        {
            this.Dal.Entry<T>(obj).State = EntityState.Deleted;
        }
        return this.Dal.SaveChanges() == 1;
    }

    public virtual bool Delete(int id)
    {
        T obj = Find(id);
        return Delete(obj);
    }

    public virtual bool Delete(Expression<Func<T, bool>> predicate)
    {
        foreach (T item in Select(predicate))
        {
            Delete(item);
        }
        return this.Dal.SaveChanges() == 1;
    }

    public virtual void Dispose()
    {
        this.Dal.Dispose();
    }
}

私たちのマネージャーは次のようになります:

public interface IBaseManager<T> : IDisposable where T : class, PrivateObject
{
    T Find(int? id);
    T Find(Expression<Func<T, bool>> predicate);
    ICollection<T> Select(Expression<Func<T, bool>> predicate = null,
        Expression<Func<T, string>> orderBy = null,
        string includeProperties = "");
    T Create(T obj);
    T Update(T obj);
    bool Delete(T obj);
    bool Delete(int id);
    bool Delete(Expression<Func<T, bool>> predicate);
    IQueryable<T> SelectAsQuery(
        Expression<Func<T, bool>> predicate = null,
        Expression<Func<T, string>> orderBy = null,
        string includeProperties = "");
}

public class BaseManager<T> : IBaseManager<T> where T : class, PrivateObject
{
    protected IBaseRep<T> Repository;

    public virtual T Find(int? id)
    {
        return this.Repository.Find(id);
    }

    public virtual T Find(Expression<Func<T, bool>> predicate)
    {
        return this.Repository.Find(predicate);
    }

    public virtual ICollection<T> Select(
        Expression<Func<T, bool>> predicate = null,
        Expression<Func<T, string>> orderBy = null,
        string includeProperties = "")
    {
        return this.Repository.Select(predicate, orderBy, includeProperties);
    }

    public virtual IQueryable<T> SelectAsQuery(
        Expression<Func<T, bool>> predicate = null,
        Expression<Func<T, string>> orderBy = null,
        string includeProperties = "")
    {
        return this.Repository.SelectAsQuery(predicate, orderBy, includeProperties);
    }

    public virtual T Create(T obj)
    {
        return this.Repository.Create(obj);
    }

    public virtual T Update(T obj)
    {
        return this.Repository.Update(obj);
    }

    public virtual bool Delete(T obj)
    {
        return this.Repository.Delete(obj);
    }

    public virtual bool Delete(int id)
    {
        return this.Repository.Delete(id);
    }

    public virtual bool Delete(Expression<Func<T, bool>> predicate)
    {
        return this.Repository.Delete(predicate);
    }

    public virtual void Dispose()
    {
        if (this.Repository != null)
            this.Repository.Dispose();
    }
}

これはうまく機能します。

ただし、複数のエンティティタイプに同じDBテーブルを使用する必要があります。

public abstract class AbstractSite : PrivateObject, IActivable, ILogicallyDeletable
{
    public int Id { get; set; }
}

public class EthicCommittee : AbstractSite
{
    public int Number { get; set; }
}

public class Site : AbstractSite
{
    public string Name { get; set; }
}

これが私たちがジェネリックマネージャーを使用する方法です:

public class AbstractSiteManager : BaseManager<AbstractSite>
{
    public AbstractSiteManager (PrismaDAL prismaDAL = null)
    {
        this.Repository = new AbstractSiteRep(prismaDAL);
    }
}

汎用リポジトリの使用方法:

public class AbstractSiteRep : PrismaBaseRep<AbstractSite>
{
    public AbstractSiteRep (PrismaDAL prismaDAL = null)
        : base(prismaDAL)
    {}
}

public class PrismaBaseRep<T> : BaseRep<T> where T : class, PrivateObject
{
    public PrismaBaseRep(PrismaDAL prismaDAL = null) : base((prismaDAL == null) ? new PrismaDAL() : prismaDAL)
    { }
}

しかし、ここでは、汎用リポジトリ/マネージャに触れることなく、抽象型ではなく具象型(AbstractSite =抽象、サイト=具象、RecruitingInstitution =具象...)を使用したいと思います。したがって、X個のジェネリックリポジトリがあります(X:具象型の数)。それらはすべて同じDBテーブルを指しています。これにより、キャストを回避し、1つのマネージャー/リポジトリを使用して操作できるタイプを制限できます。

皆さん、私がこれをどのように達成できるかについて何か考えがありますか?

4

1 に答える 1

1

私の間違いを解決しました。

@Mike Cが言ったように、これはうまく機能します。

抽象(TPH)ではなく具象オブジェクトタイプを参照している場合、EFが正しいテーブルを見つけることができることを知りませんでした。

于 2012-04-11T08:00:09.717 に答える