对DbContext的通用访问
本文关键字:访问 DbContext | 更新日期: 2023-09-27 18:27:16
ObjectContext
允许对生成的实体进行通用访问。DbContext
似乎没有这样的支持。使用通用存储库访问EF5具有挑战性。假设我想要一个通用机制来读取任何给定的实体,称之为TEntity:
public class DataRepositoryEF5<T> where T: DbContext
{
private ObjectContext _context;
public DataRepositoryEF5(DbContext context)
{
_context = ((IObjectContextAdapter)context).ObjectContext;
}
public IEnumerable<TEntity> ReadAll<TEntity>() where TEntity : class,new()
{
return GetObjectSet<TEntity>().AsEnumerable();
}
protected ObjectSet<TEntity> GetObjectSet<TEntity>() where TEntity : class,new()
{
ObjectSet<TEntity> result;
result = _context.CreateObjectSet<TEntity>();
return result;
}
}
使用
var context = new MyContext();
var repository = new DataRepositoryEF5<MyContext>(context);
IEnumerable<Document> results = repository.GetAll<Document>();
foreach (var item in results)
{
Console.WriteLine("{0} {1} {2} {3}", item.Description, item.Id, item.Property, item.Whatever);
}
EF,用于生成具有公共基类型CCD_ 3的类。由于不再是这种情况,我可以拥有的最佳约束是class
。。。
其次,因为没有ObjectContext.CreateObjectSet<>()
的等价物,所以我被迫从DbSet
转换为ObjectSet
。
有了这个模式,我就不需要DbContext
了。如果没有泛型,我就不得不手工编写所有CRUD操作的代码。我错过什么了吗?如果没有,是否可以告诉EF5使用ObjectContext
生成代码?
看看我不久前发布的这个技巧
无论如何,诀窍是使用context.Set<>
public interface IEntity
{
int Id { get; set; }
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
private IDbContext _context;
public Repository(IDbContext context)
{
_context = context;
}
private IDbSet<TEntity> DbSet
{
get
{
return _context.Set<TEntity>();
}
}
public IQueryable<TEntity> GetAll()
{
return DbSet.AsQueryable();
}
public void Delete(TEntity entity)
{
DbSet.Remove(entity);
}
.....
这是一个更新、更完整的答案。
using Library.Models;
using Library.EF;
namespace Abstractions
{
public interface IKeyedModel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
}
public class GenericContext<T> : DbContext where T : class, IKeyedModel
{
public DbSet<T> Items { get; set; } = default!;
}
public interface IRepository<T> where T : class, IKeyedModel
{
public GenericContext<T> Context() => new GenericContext<T>();
public T Select(int id) => Context().Items.Single(x => x.Id == id);
public IQueryable<T> Select() => Context().Items;
public void Insert(T item)
{
var context = Context();
context.Items.Add(item);
context.SaveChanges();
}
public void Update(T item)
{
var context = Context();
context.Items.Attach(item);
context.SaveChanges();
}
public void Delete(int id)
{
var context = Context();
var item = context.Items.Single(x => x.Id == id);
context.Items.Remove(item);
context.SaveChanges();
}
}
}
namespace Models
{
[Table(name: "User")]
public class User : IKeyedModel
{
public int Id { get; set; }
public string Name { get; set; } = default!;
}
}
namespace App
{
public class UserRepository : IRepository<User> { /* empty */ }
}