[英]Linq to SQL database context management
我有一个关于管理LINQ to SQL数据库上下文的生命周期的问题。 当前,无论何时需要,我都在使用工厂实例化新的数据库上下文。 在某些情况下这很好,但在其他情况下则不是。 例如,当一个操作跨越多个方法时,在每个方法中,我都叫工厂来生成一个新实例,而我确实需要在操作的生命周期中在方法之间共享上下文。 从理论上讲,该操作必须是原子的。 因此,我的问题是要知道在工厂中具有多个工厂方法以在需要时获取所需上下文是否是一个好的设计?
我在下面提供了一个示例实现。
//接口
public interface IEntityContextFactory : ISingletonService
{
IDbContext CreateContext();
IDbContext GetContext();
}
//工厂类
public class EntityContextFactory : IEntityContextFactory
{
private IDbContext _context;
public IDbContext CreateContext()
{
var defaultConnectionString = ConfigurationManager.ConnectionStrings["connection_name"].ConnectionString;
var database = new DataContext(defaultConnectionString);
// this is a wrapper around the linq to sql context
return new DbContext(database);
}
public IDbContext GetContext()
{
// TODO: make threadsafe
if(_context == null)
{
_context = CreateContext();
return _context;
}
return _context;
}
}
在您的方法中,这看起来像是依赖注入的工作。
要求上下文的方法应该接受一个方法,而不是接受“更新”自己的能力的方法,即使是从看似正在做同样事情的工厂那里也是如此。
如果方法可以合理地组织到一个类中,则该类的构造函数可以要求使用上下文。
最后,这是真正重要的部分,听起来您想包装可以在需要利用工厂的新方法中包装需要相同上下文的方法。
一个仓促的例子。
public class DataAccess {
private IDbContext _dbContext;
public DataAccess(IDbContext context) {
_dbContext = context;
}
// atomic example
public UserModel GetUser(int id) {
return _dbContext.UserTable
.Where(x => x.Id == id)
.FirstOrDefault();
}
// not-atomic example
public bool RecordUserActivity(UserModel user, IEnumerable<UserActivity> activities) {
try {
_dbContext.BeginTransaction();
// messy example
_dbContext.UserLogins
.Add(activities.Where(x => x.ActivityType == ActivityTypes.Logins));
_dbContext.UserEdits
.Add(activities.Where(x => x.ActivityType == ActivityTypes.Edits));
//
_dbContext.CommitTransaction();
return true;
} catch (Exception ex) {
// log your exceptions!
_dbContext.RollbackTransaction();
}
return false;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.