对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生成代码?

对DbContext的通用访问

看看我不久前发布的这个技巧

无论如何,诀窍是使用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 */ }
}