如何在EF </t>中使用<t>创建类的存储库

时间:2013-05-23 10:59:08

标签: c# entity-framework ef-code-first repository-pattern

我有一个简单的课程:

public class TestClass<T> {
    public int ID { get; set; }
    public T Value { get; set; }
}

是否可以使用EF Code First和Repository模式将这种元素保存到SQL数据库?


修改: 似乎无法使用-notation创建DbSet。例如。

public class UnitOFWorkTestContext : DbContext {
    ...
    public DbSet<TestClass<int>> TestClass_Int { get; set; }
    ...
}

给出错误:

未映射类型'UnitOFWorkTest.Models.TestClass`1 [System.Int32]'。使用Ignore方法或NotMappedAttribute数据批注检查未明确排除类型。验证类型是否已定义为类,不是原始类,嵌套类还是通用类,并且不从EntityObject继承。

2 个答案:

答案 0 :(得分:5)

以下是我自己的工作代码的副本。我不假装我的代码是完美的,但它很方便,并且具有松散的耦合性。此外,它将是相当大的代码,但不要害怕=)...

<强> IEntity:

public interface IEntity
{
    int Id { get; set; }
}

AbstractRepository和interface:

public interface IRepository<T>
{
    IEnumerable<T> List();
    IEnumerable<T> List(Func<T, bool> pred);

    T Get(int id);
    T Get(Func<T, bool> pred);

    void Add(T entity);

    T Update(T entity);

    void Delete(T entity);
    void Delete(Func<T, bool> pred);
}

public abstract class AbstractRepository<TEntity, TContext> : IRepository<TEntity>
    where TContext : DbContext, new()
    where TEntity : class, IEntity
{
    protected TContext context;

    public AbstractRepository(UnitOfWork<TContext> unit)
    {
        context = unit.Context;
    }

    public virtual IEnumerable<TEntity> List()
    {
        return context.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> List(Func<TEntity, bool> pred)
    {
        return context.Set<TEntity>().Where(pred);
    }

    public virtual TEntity Get(int id)
    {
        return context.Set<TEntity>().Find(id);
    }

    public virtual TEntity Get(Func<TEntity, bool> pred)
    {
        return context.Set<TEntity>().FirstOrDefault(pred);
    }

    public virtual void Add(TEntity entity)
    {
        if (entity.Id <= 0)
            context.Entry(entity).State = System.Data.EntityState.Added;
    }

    public virtual TEntity Update(TEntity entity)
    {
        if (entity.Id > 0)
        {
            context.Entry(entity).State = System.Data.EntityState.Modified;
            return entity;
        }
        return null;
    }

    public virtual void Delete(TEntity entity)
    {
        context.Entry(entity).State = System.Data.EntityState.Deleted;
    }

    public virtual void Delete(Func<TEntity, bool> pred)
    {
        foreach (var entity in List(pred))
        {
            Delete(entity);
        }
    }
}

具体存储库:

public class GroupRepository : AbstractRepository<Group, SurveyContext>
{
    public GroupRepository(UnitOfWork<SurveyContext> unit)
        : base(unit)
    {
    }
}

DbContext后继者:

public class SurveyContext: DbContext
{
    public SurveyContext() : base("name=ApplicationConnection")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //Optional
        modelBuilder.Configurations.Add(new Confuration1());
        modelBuilder.Configurations.Add(new Confuration2());
        modelBuilder.Configurations.Add(new Confuration3());
        modelBuilder.Configurations.Add(new GroupConfiguration());

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<Group> Groups { get; set; }
    public DbSet<Foo> Foos { get; set; }
    public DbSet<Bar> Bars { get; set; }
}

工作单位:

public class UnitOfWork<TContext> : IDisposable
    where TContext: DbContext, new()
{
    public TContext Context { get; private set; }

    public UnitOfWork(TContext context)
    {
        Context = context;
    }

    public UnitOfWork() : this(new TContext())
    {
    }

    public void Commit()
    {
        Context.SaveChanges();
    }

    public void Dispose()
    {
    }
}

<强>用法:

using (var unit = new UnitOfWork<SurveyContext>())
{
    //ViewDataSynchronize.SynchronizeSectionsForGroup(context, model.SectionIds, model.Group);

    var repo = new GroupRepository(unit);
    repo.Add(model.Group);
    unit.Commit();
}

答案 1 :(得分:1)