实体框架代码首先,工作单元,存储库和共享DbContext

时间:2011-09-10 19:03:44

标签: asp.net-mvc entity-framework ef-code-first repository-pattern unit-of-work

我正在使用EF Code First和ASP.NET MVC构建一个Web应用程序。我有以下类型:

IProblemRepository
EFProblemRepository
ICategoryRepository
EFCategoryRepository
CleanStreets // db context
IUnitOfWork
// etc.

代码段:

public interface IUnitOfWork
{
    void Save();
}

public class CleanStreets : DbContext, IUnitOfWork
{
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Point> Points { get; set; }
    public DbSet<Rating> Ratings { get; set; }
    public DbSet<Picture> Pictures { get; set; }
    public DbSet<Problem> Problems { get; set; }
    public DbSet<Comment> Comments { get; set; }
    public DbSet<Category> Categories { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .HasMany(u => u.Comments)
                    .WithRequired(c => c.User)
                    .HasForeignKey(c => c.UserID)
                    .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

    public void Save()
    {
        this.SaveChanges();
    }
}


public class EFProblemRepository : IProblemRepository
{
    private readonly CleanStreets data;

    public EFProblemRepository(CleanStreets data)
    {
        this.data = data;
    }        

    public void Save(Problem problem)
    {
        if (problem.ProblemID == 0)
        {
            data.Problems.Add(problem);
        }

        data.Save();
    }
    ...
}

起初,我没有UnitOfWork。我在每个存储库中创建了一个新上下文。但在我想保存ProblemProblem包括Category)后,使用上面提供的保存方法,我收到以下错误:

  

IEntityChangeTracker的多个实例

无法引用实体对象

我发现,在stackoverflow上,问题出在我的db上下文中,解决方案是使用工作单元模式创建共享上下文。我试着这样做(正如你上面所见),但我仍然得到错误。每当我想存储Problem错误弹出时。我是否实现了“共享”数据库上下文?

1 个答案:

答案 0 :(得分:1)

根据错误消息,您可能需要从一个上下文中分离对象以将其保存在另一个上下文中。您还可以构造从第一个复制的新对象(此处需要深层复制)以执行此操作。还需要额外的思考来处理没有对象引用副本的任何外键。