我想知道如何获得我将用EF6解释的这种行为。
想象一下,我有DbContext
,我正在对其进行操作,查询,删除和添加相关DbSets上的记录。
想象一下,我有来自DB的Person DbSet最初有3条记录
我这样做:
using (var pc = new PersonContext())
{
pc.Persons.Add(new Person("Mario","Rossi"));//add 1 record
var pcount=pc.Persons.Count();//still 3 recors and not 4 as expected
//Complex opertions...
pc.SaveChanges();
}
我想将DbSets与DbContext更新(删除,添加,修改)记录一起使用,而不必每次都调用SaveChanges
方法。
想象一下,在最终SaveChanges
之前,我可以执行大量复杂的操作。
这不仅仅是关于交易,因为我知道我可以获得这样的东西:
using (var pc = new PersonContext())
{
pc.Database.BeginTransaction();
pc.Persons.Add(new Person("Mario","Rossi"));//add 1 record
pc.SaveChanges();
var pcount=pc.Persons.Count();//4 as expected
//Complex opertions
pc.Database.CurrentTransaction.Commit();
}
考虑到跟踪变化,有没有办法获得这个而不必编写大量代码?
答案 0 :(得分:0)
1.首先创建一个Generic Repository接口:
public interface IRepository<T> : IDisposable
where T : class
{
IQueryable<T> GetAll();
T FirstOrDefault(Expression<Func<T, bool>> predicate);
T Create(T item);
int Update(T item);
int Delete(T item);
}
2.然后是通用存储库:
public class Repository<T> : IRepository<T> where T : class
{
private DbContext _context;
private DbSet<T> DbSet
{
get { return _context.Set<T>(); }
}
public Repository(DbContext context)
{
this._context = bookContext;
}
public IQueryable<T> GetAll()
{
return DbSet.AsNoTracking().AsQueryable();
}
public T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
return DbSet.FirstOrDefault(predicate);
}
public T Create(T item)
{
if (item == null)
throw new ArgumentNullException(nameof(item));
using (var scope = new TransactionScope())
{
DbSet.Add(item);
_context.SaveChanges();
scope.Complete();
return item;
}
}
public int Update(T item)
{
if (item == null)
throw new ArgumentNullException(nameof(item));
using (var scope = new TransactionScope())
{
var entry = _context.Entry(item);
DbSet.Attach(item);
entry.State = EntityState.Modified;
var result= _context.SaveChanges();
scope.Complete();
return result;
}
}
public int Delete(T item)
{
if (item == null)
throw new ArgumentNullException(nameof(item));
using (var scope = new TransactionScope())
{
DbSet.Remove(item);
var result= _context.SaveChanges();
scope.Complete();
return result;
}
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
3.创建人员存储库:
public interface IPersonRepository : IRepository<Person>
{
}
public class PersonRepository : Repository<Person>, IPersonRepository
{
public PersonRepository(DbContext context) : base(context) { }
}
4.使用: 例如:
PersonContext context= new PersonContext();
IPersonRepository _personRepository= new PersonRepository(context);
_personRepository.Create(new Person("Mario","Rossi"));
OR 使用IoC container进行依赖注入。(我强烈推荐这个)。 和使用(ASP.NET MVC的示例)
public class PersonController:Controller
{
IPersonRepository _personRepository;
public PersonController(IPersonRepository personRepository){
_personRepository=personRepository;
}
public ActionResult Create()
{
var person= _personRepository.Create(new Person("Mario","Rossi"));
return View();
}
}
的Microsoft文档
答案 1 :(得分:0)
由于DbSet总是会从数据库中为您提供数据,因此没有一种自动方式从框架中执行我想要的操作。
有一个名为&#39; Local&#39;的特定DbSet属性。 (https://msdn.microsoft.com/en-us/library/system.data.entity.dbset.local(v=vs.113).aspx#P:System.Data.Entity.DbSet.Local)表示此集合中所有已添加,未更改和已修改实体的本地视图。
最后,我们应该从DbSet查询开始编写一些代码,并在结果列表中应用跟踪到DbSet.Local集合中的操作。