1

我有一个简单的课程:

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 继承的。

4

1 回答 1

5

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

实体:

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

AbstractRepository 和接口:

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();
}
于 2013-05-23T11:29:30.537 回答