Реализация этого общего хранилища, единицы работы и фабрики хранилищ - PullRequest
0 голосов
/ 02 апреля 2011

Я немного изменил это, удалил один метод из исходного поста, где я нашел этот пример. Вот общий репозиторий.

/// <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.

1 Ответ

3 голосов
/ 02 апреля 2011

Как насчет этого:

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

Фабрика для репозиториев на основе типа TEntity имеет смысл, только если у вас есть информация о строке соединений с EDMX, используемая для сопоставления типа сущности.Но такая информация должна быть жестко запрограммирована на заводе, или, может быть, я не понимаю ваш вопрос.

Кстати.Ваш общий подход полностью потерпит неудачу, как только вы попытаетесь его использовать.Он отлично работает для операций CRUD с одним объектом без отношений, но как только вы начнете использовать его на реальных объектах или объединить корни, у вас будет так много проблем.Просто просмотрите вопросы, помеченные и , и вы увидите.

...