c#存储库模式和lambdas,如何转换类型

时间:2016-06-22 10:05:22

标签: c# entity-framework repository dto

我正在尝试使用数据传输对象和单独的数据提供程序构建一个Entity框架抽象存储库。我们需要能够在oracle,sql server和azure sql之间切换,具体取决于安装。

结束存储库将DTO返回给使用代码。获取,更新和删除工作正常。我遇到的问题是使用l​​ambdas for where子句等。通用存储库不知道数据提供者的实际Entity对象,因此我无法创建where lambda。

P.S。使用AutoMapper在实体和DTO之间进行转换

//Repository base
public class Repository<TEntity> : IDisposable, IRepository<TEntity> where TEntity : class, IEntity
{
    public virtual IList<TEntity> GetList(Func<TEntity, bool> where, params Expression<Func<TEntity, object>>[] navigationProperties)
    {
        List<TEntity> list;

        IQueryable<TEntity> dbQuery = Context.Set<TEntity>();

        //Apply eager loading
        foreach (Expression<Func<TEntity, object>> navigationProperty in navigationProperties)
            dbQuery = dbQuery.Include<TEntity, object>(navigationProperty);

        list = dbQuery
            .AsNoTracking()
            .Where(where)
            .ToList<TEntity>();

        return list;
    }
}

//Implementing repository where T is the entity from the EF model
public class UserRepository<T> : IUserRepository, IUnitOfWork
    where T : class, IEntity
{
    public Repository<T> Base { get; private set; }

    public UserRepository(DbContext context)
    {
        Base = new Repository<T>(context);
    }

    public List<UserAccountDTO> GetList(Expression<Func<UserAccountDTO, bool>> where)
        {
            T obj = SupportedRepos.DTOMapper.Map<T>(where.Parameters[0]);
                /* HOW CAN I CONVERT THE FUNC<>? */
                //Base.GetList();
                return null;
        }
    }

public void TestMethod1()
{
    var dbtypeFromConfig = RepoEF.Setup.StorageType.SQLServer;

    using (var repo = RepoEF.Setup.SupportedRepos.Create(dbtypeFromConfig))
    {
        //WORKS FINE, CHANGES AND UPDATES
        var source = repo.Get(3);
        source.LookupId = 111111;
        repo.Add(source);

        //CAN'T CREATE WHERE BECAUSE UserRepository<T> ONLY SEES IEntity
        repo.GetList(x => x.UserAccountId == 3);
    }
}

是否可以构建一个Func&lt;&gt;传递给基础存储库。

如果没有任何想法我如何改变设计以实现我的需要?

1 个答案:

答案 0 :(得分:1)

也许我可以深入了解您当前的存储库模式实现并尝试修复它,但我相信,毕竟还有许多设计缺陷会迫使您完全重构您的解决方案。

所以我会给你一些提示:

1)存储库仍然是,因此它始终与域对象一起使用

域名不应与DTO合作。如果要在逻辑或物理边界之间传输数据,可以使用DTO模式。例如,当域服务需要向应用程序服务提供某些域对象的列表时。该列表将作为域对象列表的DTO公开。

2)数据库技术交换机是数据映射层(即实体框架)的责任。

您的存储库应该与数据库技术保持一致,并与OR / M框架结合使用。

3)如果用户存储库 IS 存储库,则应使用继承而不是组合

因此,UserRepository应该实现IUserRepository并从Repository<User>派生。

4)具体的存储库不应该接受泛型类型参数来提供域对象来处理

在一天结束时,像IUserRepository这样的具体存储库处理User的实例,因此,为什么需要TEntity通用参数?既然你有这个设计缺陷,TEntity不是T ......这就是你要解决的问题背后的原因......