2013-04-28 62 views
0

我正在使用实体框架将数据保存在N层Wpf应用程序中。我的dbcontext在所有存储库之间共享,并且永远不会丢弃。当我坚持数据时,我将一个对象标记为已修改,并尝试保存更改。如果在持久化对象时出现错误,则对象仍被标记为已修改,并且如果用户中止当前操作,则在保存另一个对象时他将得到相同的错误。使用单个dbcontext时发生异常后恢复

我已经在我的DbContext覆盖的SaveChanges,如果任何错误accurs我接受所有的变化(见下面的代码)解决了这个。所以如果一个错误产生了对象,并且所有对象都被标记为未改变,即使他们没有持续。

这感觉不对...... 有谁这个解决方案同意吗? 另一个解决方案是在我的存储库中的每个方法中新建dbcontext并立即处理它们。这将使我的存储库更加复杂和“noicy”,我也将失去延迟加载数据的能力... 有没有人对我有不同的解决方案?

//In my repositories 
    public void UpdateObject(Object object) 
    { 
     dbContext.Entry(object).State = EntityState.Modified; 
     dbContext.SaveChanges(); 
    } 

    //In my dbcontext class 
    private ObjectContext ObjectContext() 
    { 
     return (this as IObjectContextAdapter).ObjectContext; 
    } 

    public override int SaveChanges() 
    { 
     try 
     { 
      return base.SaveChanges(); 
     } 
     catch (Exception) 
     { 
      ObjectContext().AcceptAllChanges(); 
      throw; 
     } 
    } 

回答

0

我们的团队使用了类似的方法如下所示:

库:

public class StudentRepository 
{ 
    private readonly MyEntities _context; 

    public StudentRepository(MyEntities context) 
    { 
    _context = context; 
    } 

    // Basic CRUD methods etc 
} 

业务逻辑:

public AddStudent(Student student) 
{ 
    using(var context = new MyEntities()) 
    { 
     var studentrepo = new StudentRepository(context); 
     studentrepo.Add(student); 
     context.SaveChanges(); 
    } 
} 

这是一个过于简单的例子,但应该给你一个理念。为了减少代码,我们还为CRUD方法使用了一个基本的通用存储库类。

如果我们正在从事的项目包括一个Web服务,我们实例化的API控制器中的DbContext和覆盖Dispose方法来摆脱它。

+0

思为您answear :) 我曾想过你的解决方案,对我来说不能很好地工作。我正在使用TDD和依赖注入。 回购是通过构造函数注入在我的业务逻辑中发送的。有了你的解决方案,我将不得不为dbcontext建立一个工厂,并为每个存储库建立一个工厂。 这感觉就像过分复杂的业务逻辑和业务逻辑与事关他们...... – Jakob 2013-04-29 09:32:29

+0

在上面的业务逻辑中,dbcontext和存储库都可以通过构造函数注入。就像我在回答中提到的,这只是一个简单的例子。如果您使用关键字(如dbcontext作用域生存期)对Google进行了一些研究,则会发现大多数ppl建议使用短期上下文。根据我自己的经验,我们发现了一个人忘记处理上下文的错误,并且它在Web服务上引起了50ms的查询,需要3.2分钟才能执行。 – failedprogramming 2013-04-30 22:00:52

0

有这样一个长期存在的上下文是不是一个好主意。随着所有实体和变化的跟踪,它会变得很大并且很慢,并发性相关的问题可能会出现,并且由您的上下文引发的异常可能会影响您的整个应用程序。

http://msdn.microsoft.com/en-us/data/jj729737

另一种解决方案是新的,在我的 repositores每种方法的DbContext和马上他们的处置。这将使我 仓库进行更复杂,“noicy”,我也将失去 能力延迟加载数据

在断开连接的情况下我会创建和工作的每一个请求/单位处置。担心你的回购变得复杂?那么不要使用这个额外的抽象层。回购是否真的有必要?你直接使用DbContext获得什么?

至于延迟加载,我认为在断开连接的n层场景,延迟加载是不是真的合适。您可能应该为视图使用所需数据的急切加载,或者使用单独的方法调用来获取相关数据。

+0

认为你的answear :) 为了清理我的数据库层是serperate,我不暴露任何东西从实体框架。我只公开poco对象(代码第一),所以我可以轻松地更改我的db层。我在wpf客户端中使用db层,并计划在Web应用程序和Web服务中使用它。在后一种情况下,每次请求后很容易处理上下文。 我担心的是代码复制和处理上下文和性能。 你仍然认为你的解决方案对我来说是最好的吗? 在你发送的链接中声明“可以工作的一个dbcontext”。 – Jakob 2013-04-29 09:23:24

相关问题