【问题标题】:Implementing this generic repository, unit of work and repository factory实现这个通用存储库、工作单元和存储库工厂
【发布时间】:2011-04-02 16:34:04
【问题描述】:

我从找到这个示例的原始帖子中对此进行了一些修改,删除了一种方法。这是通用存储库。

/// <summary>
/// Repository base class used with DbContext Originally From http://dotnetspeak.com/index.php/2011/03/repository-pattern-with-entity-framework/
/// </summary>
/// <typeparam name="TContext">Type of DdContext that this repositiory operates on</typeparam>
public class RepositoryBase<TContext> : IDisposable, IRepositoryBase where TContext : DbContext, IObjectContextAdapter, new()
{
    private DbContext _dbContext;
    public DbContext CurrentContext { get; set; }

    /// <summary>
    /// Create new instance of repository
    /// </summary>
    /// <param name="DbContext">For embeded edmx resource please define base("name=yourAppEntities") in a class derrived from DBContext</param>
    public RepositoryBase(DbContext _context)
    {
        _dbContext = new TContext();
        CurrentContext = _dbContext;
    }
    /// <summary>
    /// Select data from database
    /// </summary>
    /// <typeparam name="TItem">Type of data to select</typeparam>
    /// <returns></returns>
    public IQueryable<TItem> Select<TItem>()
       where TItem : class, new()
    {
        DbSet<TItem> _set = _dbContext.Set<TItem>();
        return _set;
    }
    /// <summary>
    /// Insert new item into database
    /// </summary>
    /// <typeparam name="TItem">Type of item to insert</typeparam>
    /// <param name="item">Item to insert</param>
    /// <returns>Inserted item</returns>
    public TItem Insert<TItem>(TItem item)
        where TItem : class, new()
    {
        DbSet<TItem> _set = _dbContext.Set<TItem>();
        _set.Add(item);
        _dbContext.SaveChanges();

        return item;
    }
    /// <summary>
    /// Update an item
    /// </summary>
    /// <typeparam name="TItem">Type of item to update</typeparam>
    /// <param name="item">Item to update</param>
    /// <returns>Updated item</returns>
    public TItem Update<TItem>(TItem item)
        where TItem : class, new()
    {
        DbSet<TItem> _set = _dbContext.Set<TItem>();
        _set.Attach(item);
        _dbContext.Entry(item).State = System.Data.EntityState.Modified;
        _dbContext.SaveChanges();
        return item;
    }
    /// <summary>
    /// Delete an item
    /// </summary>
    /// <typeparam name="TItem">Type of item to delete</typeparam>
    /// <param name="item">Item to delete</param>
    public void Delete<TItem>(TItem item)
       where TItem : class, new()
    {
        DbSet<TItem> _set = _dbContext.Set<TItem>();
        var entry = _dbContext.Entry(item);
        if (entry != null)
        {
            entry.State = System.Data.EntityState.Deleted;
        }
        else
        {
            _set.Attach(item);
        }
        _dbContext.Entry(item).State = System.Data.EntityState.Deleted;
        _dbContext.SaveChanges();
    }


    /// <summary>
    /// Dipose repository
    /// </summary>
    public void Dispose()
    {
        if (_dbContext != null)
        {
            _dbContext.Dispose();
            _dbContext = null;
        }
    }
}

我将如何为此实现 DbContext 工厂?如您所见,构造函数采用 DbContext,当使用编译到程序集中的 edmx 文件时,您必须传入一个派生自 DbContext 的类,如下所示:

public class ContextWrapper: DbContext
{
    public string _connectionString { get; set; }
    public ContextWrapper()
        : base("name=" + ConfigurationManager.ConnectionStrings["MyEFStringName"].Name)
    {
        _connectionString = this.Database.Connection.ConnectionString;


    }
}

忽略 _connectionstring get;set;这是为了测试。

对我来说,这似乎很臭,因为您必须硬编码 EF 连接字符串名称的名称。

我想找到一种方法来围绕这个实现工厂,这也是通用的。所以我们可以有一个基于 TEntity 生成的存储库。

【问题讨论】:

    标签: c# generics repository-pattern entity-framework-4.1


    【解决方案1】:

    这个呢:

    public class ContextWrapper : DbContext
    {
        public ContextWrapper(string ConnectionStringName)
            : base("name=" + ConnectionctionStringName)
        { }
    }
    

    基于 TEntity 类型的存储库工厂只有在您有关于用于映射实体类型的 EDMX 的连接字符串的信息时才有意义。但是这些信息必须硬编码到工厂或者我不明白你的问题。

    顺便说一句。一旦您尝试使用它,您的通用方法将完全失败。它非常适用于没有关系的一个实体的 CRUD 操作,但是一旦你开始在真实实体或聚合根上使用它,你就会遇到很多问题。只需浏览带有 标记的问题,您就会看到。

    【讨论】:

    • 它在有关系的实体上工作得很好,它可以从 UnitOfWork 中受益,我正在这样做。我不明白你怎么能说它会完全失败,你没有这个说法的依据。
    • 问题不在于 Wrapper 类或连接字符串,更多的是关于如何在 DBContext 的存储库中创建通用工厂。
    猜你喜欢
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    相关资源
    最近更新 更多