【问题标题】:PetaPoco + unit of work + repository patternPetaPoco + 工作单元 + 存储库模式
【发布时间】:2016-05-10 05:48:54
【问题描述】:

下面的代码似乎可以使用这个:

var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider();
var repository = new FakeRepository();
var fake = new Fake
{     
    // etc.
};

using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString"))
{
    repository.Insert(uow, fake);
    uow.Commit();
}

最终可能会进入服务层。我将不胜感激任何改进此代码的反馈。

public interface IUnitOfWork : IDisposable
{
    void Commit();
    Database Database { get; }
}

public interface IUnitOfWorkProvider
{
    IUnitOfWork GetUnitOfWork(string connectionString);
}

public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
    public IUnitOfWork GetUnitOfWork(string connectionString)
    {
        return new PetaPocoUnitOfWork(connectionString);
    }
}

public interface IRepository<T>
{
    void Insert(IUnitOfWork unitOfWork, T entity);
    void Update(IUnitOfWork unitOfWork, T entity);
    void Delete(IUnitOfWork unitOfWork, T entity);
    T Fetch(IUnitOfWork unitOfWork, long uid);
}

public class PetaPocoUnitOfWork : IUnitOfWork
{
    private readonly Transaction _petaTransaction;
    private readonly Database _database;

    public PetaPocoUnitOfWork(string connectionString)
    {
        _database = new Database(connectionString);
        _petaTransaction = new Transaction(_database);
    }

    public void Dispose()
    {
        _petaTransaction.Dispose();
    }

    public Database Database
    {
        get { return _database; }
    }

    public void Commit()
    {
        _petaTransaction.Complete();
    }
}

public class FakeRepository : IRepository<Fake>
{
    public void Insert(IUnitOfWork unitOfWork, Fake entity)
    {
        unitOfWork.Database.Save(entity);
    }

    public void Update(IUnitOfWork unitOfWork, Fake entity)
    {
        unitOfWork.Database.Update(entity);
    }

    public void Delete(IUnitOfWork unitOfWork, Fake entity)
    {
        unitOfWork.Database.Delete(entity);
    }

    public FakeJobFact Fetch(IUnitOfWork unitOfWork, long uid)
    {
        return unitOfWork.Database.Fetch<Fake>("SELECT * FROM Fakes WHERE [FakeId] = @0", uid).FirstOrDefault();
    }
}

PS:

我已根据@Plebsori 当前答案修改了代码:

public abstract class BaseRepository<T>
{
    protected IDatabase Database
    {
        get
        {
        return UnitOfWork.Current;
        }
    }

    public void Insert(T entity)
    {
        Database.Save(entity);
    }

    public void Update(T entity)
    {
        Database.Update(entity);
    }

    public void Delete(T entity)
    {
        Database.Delete(entity);
    }
}

public interface IRepository<T>
{
    void Insert(T entity);
    void Update(T entity);
    void Delete(T entity);
    T Fetch(long uid);
}

public interface IUnitOfWork : IDisposable
{
    void Commit();
    Database Database { get; }
}

public interface IUnitOfWorkProvider
{
    IUnitOfWork GetUnitOfWork(string connectionString);
}

public class PetaPocoUnitOfWork : IUnitOfWork
{
    private readonly Transaction _petaTransaction;
    private readonly Database _database;

    public PetaPocoUnitOfWork(string connectionString)
    {
        _database = new Database(connectionString);
        _petaTransaction = new Transaction(_database);
    }

    public void Dispose()
    {
        UnitOfWork.Current = null;
        _petaTransaction.Dispose();
    }

    public Database Database
    {
        get { return _database; }
    }

    public void Commit()
    {
        _petaTransaction.Complete();
    }
}

public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
    public IUnitOfWork GetUnitOfWork(string connectionString)
    {
        if (UnitOfWork.Current != null)
        {
        throw new InvalidOperationException("Existing unit of work.");
        }

        var petaPocoUnitOfWork = new PetaPocoUnitOfWork(connectionString);
        UnitOfWork.Current = petaPocoUnitOfWork.Database;
        return petaPocoUnitOfWork;
    }
}

public static class UnitOfWork
{
    [ThreadStatic] public static IDatabase Current;
}

【问题讨论】:

  • 您能否详细说明“IDatabase”接口应该是什么?另外,您对这种方法满意吗?

标签: c# repository unit-of-work petapoco


【解决方案1】:

您可能喜欢也可能不喜欢,但这是我如何从界面中删除传递工作单元和工作单元的方法。

var unitOfWorkProvider = new PetaPocoUnitOfWorkProvider();
var repository = new FakeRepository();
var fake = new Fake
{     
    // etc.
};

using (var uow = unitOfWorkProvider.GetUnitOfWork("BlaConnectionString"))
{
    repository.Insert(fake);
    uow.Commit();
}

代码

public interface IUnitOfWorkProvider
{
    IUnitOfWork GetUnitOfWork(string connectionString);
}

public static class UnitOfWork
{
    [ThreadStatic]
    public static IUnitOfWork Current { get; set; }
}

public class PetaPocoUnitOfWorkProvider : IUnitOfWorkProvider
{
    public IUnitOfWork GetUnitOfWork(string connectionString)
    {
        if (UnitOfWork.Current != null) 
        {
           throw new InvalidOperationException("Existing unit of work.");
        }
        UnitOfWork.Current = new PetaPocoUnitOfWork(connectionString);
        return UnitOfWork.Current;
    }
}

public interface IRepository<T>
{
    void Insert(T entity);
    void Update(T entity);
    void Delete(T entity);
    T Fetch(long uid);
}

public class PetaPocoUnitOfWork : IUnitOfWork
{
    private readonly Transaction _petaTransaction;
    private readonly Database _database;

    public PetaPocoUnitOfWork(string connectionString)
    {
        _database = new Database(connectionString);
        _petaTransaction = new Transaction(_database);
    }

    public void Dispose()
    {
        UnitOfWork.Current = null;
        _petaTransaction.Dispose();
    }

    public Database Database
    {
        get { return _database; }
    }

    public void Commit()
    {
        _petaTransaction.Complete();
    }
}

public abstract class BaseRepository<T> : IRepository<T>
{
    protected IDatabase Db
    {
        get
        {
            return UnitOfWork.Current;
        }
    }
}

public class FakeRepository : BaseRepository<T>
{
    public void Insert(Fake entity)
    {
        Db.Save(entity);
    }

    public void Update(Fake entity)
    {
        Db.Update(entity);
    }

    public void Delete(Fake entity)
    {
        Db.Delete(entity);
    }

    public FakeJobFact Fetch(long uid)
    {
        return Db.Fetch<Fake>("SELECT * FROM Fakes WHERE [FakeId] = @0", uid).FirstOrDefault();
    }
}

【讨论】:

  • 我喜欢这个谢谢。是的,一直通过 uow 感觉不对。只是好奇- UnitOfWork.Current 是否确保 repo 仅使用属于 using 范围的 uow ?谢谢!
  • 更新了代码示例以在存在另一个工作单元时抛出。它将停止嵌套的工作单元。但是,由于静态是线程静态的,这种设计意味着多个线程将各自拥有自己的作用域。
  • 如果 Current 不是静态的,ThreadStatic 的用途是什么?
  • 为您更新了代码。我手写这个是为了给你一个想法
  • 啊,是的,抱歉,应该是抽象的。 (更新)。另一种是c#6语法,更新到版本5。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
相关资源
最近更新 更多