我通常将以下设置与 EF 端结构图一起使用:(振作起来,一堆代码即将出现)。
这是我们将用来注入控制器的基本接口:
public interface ISession : IDisposable
{
void CommitChanges();
void Delete<T>(Expression<Func<T, bool>> expression) where T : class, new();
void Delete<T>(T item) where T : class, new();
void DeleteAll<T>() where T : class, new();
T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();
IQueryable<T> All<T>() where T : class, new();
void Add<T>(T item) where T : class, new();
void Add<T>(IEnumerable<T> items) where T : class, new();
void Update<T>(T item) where T : class, new();
}
这里有一个考虑到 EF 的 ISession 实现:
public class EntityFrameworkSession : ISession
{
// MyContext is a class inheriting from EF's DbContext
readonly DbContext _context;
public EntityFrameworkSession(DbContext context)
{
_context = context;
}
public void CommitChanges()
{
_context.SaveChanges();
}
public void Delete<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
var query = All<T>().Where(expression);
foreach (var item in query)
{
Delete(item);
}
}
public void Delete<T>(T item) where T : class, new()
{
_context.Set<T>().Remove(item);
}
public void DeleteAll<T>() where T : class, new()
{
var query = All<T>();
foreach (var item in query)
{
Delete(item);
}
}
public void Dispose()
{
_context.Dispose();
}
public T Single<T>(Expression<Func<T, bool>> expression)
where T : class, new()
{
return All<T>().FirstOrDefault(expression);
}
public IQueryable<T> All<T>() where T : class, new()
{
return _context.Set<T>().AsQueryable();
}
public void Add<T>(T item) where T : class, new()
{
_context.Set<T>().Add(item);
}
public void Add<T>(IEnumerable<T> items) where T : class, new()
{
foreach (var item in items)
{
Add(item);
}
}
public void Update<T>(T item) where T : class, new()
{
//nothing needed here
}
}
现在这个ISession 实现注入起来不是很方便,因为虽然它既好又通用,但它没有默认构造函数,所以解决它的方法是编写一个只公开一个参数的小包装器-更少的构造函数:
/// <summary>
/// This is the EF site alternative
/// </summary>
public class SiteEFSession : EntityFrameworkSession
{
public SiteEFSession() : base(new MyContext())
{ }
}
现在我们可以轻松地注入它。我们在StructureMap中设置如下:
ObjectFactory.Initialize(x =>
{
x.For<ISession>().Use<SiteEFSession>();
});
如果你有,例如,一个 MVC 风格的控制器:
public class HomeController : Controller
{
private readonly ISession _session;
// ISession will be injected automatically
public HomeController(ISession session)
{
_session = session;
}
}
你去。这是一大堆代码,但您几乎可以将其复制/粘贴到您的解决方案中,您应该一切顺利。