当前位置: 首页 > 知识库问答 >
问题:

实体框架4.1通用存储库的设置

伏星汉
2023-03-14
public class MyRepository
{
    private const string containerName = "myEntities";
    private readonly ObjectContext context;
    private readonly Hashtable objectSets;

    // Track whether Dispose has been called.
    private bool disposed;

    public MyRepository()
    {
        string connectionString = ConfigurationManager.ConnectionStrings[containerName].ConnectionString;

        context = new ObjectContext(connectionString) {DefaultContainerName = containerName};
        context.ContextOptions.LazyLoadingEnabled = true;
        context.ContextOptions.ProxyCreationEnabled = true;

        objectSets = new Hashtable();
    }

    private ObjectSet<TEntity> GetObjectSet<TEntity>() where TEntity : class
    {
        ObjectSet<TEntity> objectSet;

        var type = typeof (TEntity);
        if (objectSets.ContainsKey(type))
        {
            objectSet = objectSets[type] as ObjectSet<TEntity>;
        }
        else
        {
            objectSet = context.CreateObjectSet<TEntity>();
            objectSets.Add(type, objectSet);
        }

        return objectSet;
    }

    public IQueryable<TEntity> GetAll<TEntity>(params string[] entities) where TEntity : class
    {
        ObjectQuery<TEntity> objectQuery = GetObjectSet<TEntity>();

        foreach (var entity in entities)
        {
            objectQuery = objectQuery.Include(entity);
        }

        return objectQuery;
    }


    public void Insert<TEntity>(TEntity entity) where TEntity : class
    {
        ObjectSet<TEntity> objectSet = GetObjectSet<TEntity>();
        objectSet.AddObject(entity);
    }

    public void Update<TEntity>(TEntity entity) where TEntity : class
    {
        ObjectSet<TEntity> objectSet = GetObjectSet<TEntity>();

        EntityKey key = objectSet.Context.CreateEntityKey(objectSet.EntitySet.Name, entity);

        object originalItem;
        if (objectSet.Context.TryGetObjectByKey(key, out originalItem))
        {
            objectSet.ApplyCurrentValues(entity);
        }
        else
        {
            objectSet.Attach(entity);
            objectSet.ApplyCurrentValues(entity);
        }
    }

    public void Delete<TEntity>(TEntity entity) where TEntity : class
    {
        ObjectSet<TEntity> objectSet = GetObjectSet<TEntity>();
        objectSet.DeleteObject(entity);
    }

    public void SaveChanges()
    {
        try
        {
            context.SaveChanges();
        }
        catch (Exception ex)
        {
            ex.ToString();
            throw ex;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        // Take yourself off the Finalization queue 
        // to prevent finalization code for this object
        // from executing a second time.
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Check to see if Dispose has already been called
        if (!disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        disposed = true;
    }

    ~MyRepository()
    {
        Dispose(false);
    }
}
public interface IEntityRepository : IDisposable
{
    void Delete<TEntity>(TEntity entity) where TEntity : class;

    IQueryable<TEntity> GetAll<TEntity>(params string[] entities) where TEntity : class;

    void Insert<TEntity>(TEntity entity) where TEntity : class;

    void Update<TEntity>(TEntity entity) where TEntity : class;

    void SaveChanges();
}

共有1个答案

司马念
2023-03-14

使用通用存储库而不是每个聚合根都有具体的存储库实现的主要缺点是,您不能为特定的用法创建特定的方法。

让所有的存储库都从基存储库继承,就可以创建类似:GetProductsSock()或类似UpdateOnlyProductsThatSatisfySomething()的方法。

但是有些变通方法是可用的!;-)

您只需将其添加到irepository接口:

IEnumerable<T> Find(Specification<T> predicate);

repository类中的方法实现如下所示:

public class Repository<T> : IRepository<T> where T : class
{
  public Repository(IDbContext context)
  {
    _context = context;
    _dbset   = context.Set<T>();
  }

  // some code...

  public IEnumerable<T> Find(Specification<T> specification)
  {
    return _dbset.Where(specification.Predicate);
  }

  // some code...
}

规范类可以如下所示:

public class Specification<T>
{
  public Specification(Expression<System.Func<T, bool>> predicate)
  {
    _predicate = predicate;
  }

  internal Expression<System.Func<T, bool>> Predicate
  {
    get { return _predicate; }
  }

  private readonly Expression<System.Func<T, bool>> _predicate;
}

一个调用示例:

var specification = ProductSpecification.InStock();
var product = Repository.Find(specification).FirstOrDefault();
internal static class ActionSpecification
{
  internal static Specification<Product> InStock()
  {
    return new Specification<Product>(p => p.IsInStock == true);
  }
}
 类似资料:
  • 问题内容: 我已经为Entity Framework 4实现了通用存储库。这是一个简化版本,其中AllAppContainer是EF4对象上下文: 一种方法是QueryCount(),我想将其用作 select Count(*)… SQL行(不返回实际记录)。 直截了当?您可能会想…首先,让我们做同一件事的非存储库版本,对Item实体进行计数: SQL Server Profiler说生成的SQL

  • 我试图使用Azure Key Vault来存储实体框架的web api连接字符串。理想情况下,我希望避免将key vault nuget包与我的数据访问代码耦合。我的dbContext类有两个构造函数: 我的代码使用了从web配置中获取连接字符串的无参数构造函数。我在某些地方实例化了一个新的MyDbContext对象,这禁止了使用注入的解决方案。 我采用的路线是在我的dbcontext上设置一个带

  • 问题内容: 我有一个简单的问题,即与“ not in” SQL等效项有关的实体框架语法。本质上,我想将以下SQL语法转换为Entity Framework语法: 这是我用于查找单个记录的方法: 这是我要用于此的伪方法: 谁能给我指点一下条款区域的内容吗?我阅读了一些有关此的论坛,并提到了使用或的情况,但是没有一个例子非常合适。 问题答案: 快去… 这些将大致变成以下数据库查询: 或者 分别。

  • 有几个很好的博客关于如何使用泛型类实现存储库模式和工作单元模式。 使用实体框架6.1实现数据访问层 实现存储库和工作单元模式 这个想法是,定义一个通用接口IRepository和一个隐藏数据实际访问方式的类存储库。可以使用实体框架DbContext来访问它,或者存储库可能是用于单元测试的内存集合。 我经常看到添加了几个与Queryable和/或Enumerable函数类似的Query函数。 例如,

  • 我有几个实体,并使用Spring Data JPA存储库与规范查询我的数据库。因此,我创建了一个泛型类< code>SpecBuilder来基于查询描述(< code>MyQueryDescriptor)构建我的查询。 我的存储库: 和 现在有三件事我不太确定:< br> 1) 使用泛型SpecBuilder是一个干净的设计吗? 2) 有没有办法避免为每个实体编写这些存储库接口?假设一个通用存储库

  • 在我的场景中,我在运行时在“com.mrg.domain”包下生成hibernate实体类。在我的通用restcontroller中,我可以根据@PathVariable创建这些实体的实例。以下代码适用于此。。 现在,我试图实现的下一步是一个通用的jpa存储库(如下所示),这样我就可以持久化运行时生成的模型,而无需为每个实体实现存储库。但是还没有找到解决方案。 下面的主题和许多其他主题实现了通用存