通用存储库是否需要将基础实体类应用于任何地方? [英] Does a Generic Repository need a Base Entity class to be applied everywhere?

查看:127
本文介绍了通用存储库是否需要将基础实体类应用于任何地方?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP.NET MVC和洋葱体系结构创建一个Intranet网站.我一直在执行存储库模式,但是有一个困难.

I am creating an Intranet website with ASP.NET MVC and Onion Architecture. I have been implementing the repository pattern but I have a difficulty.

假设我有一个包含IDDocument的Document表.然后,这是我的存储库(仅一种方法):

Let's say I have a Document table with IDDocument in it. Then this is my repo(with just one method):

class Repository<T> : IRepository<T> where T : class
{
    private readonly PrincipalServerContext context;
    private DbSet<T> entities;
    //Constructor and stuff here
    public T Get(long id)
    {
        return entities.SingleOrDefault(s => s.IDDocument == id);//Here is my problem
    }
}

问题是我不能使用它,因为T不被识别为来自文档表.解决方案是创建一个BaseEntity:

The problem is that I cannot use this since T is not recognized as being from Document table. Solution is to create a BaseEntity:

public class BaseEntity{
  public int ID{get;set;}
}

然后我的文档POCO变为:

Then My Document POCO becomes:

public class Document : BaseEntity{ 
   //Properties here
}

还有我的仓库:

 class Repository<T> : IRepository<T> where T : BaseEntity
    {
        private readonly PrincipalServerContext context;
        private DbSet<T> entities;
        public T Get(long id)
        {
            return entities.SingleOrDefault(s => s.ID == id);//Here is my problem
        }
    }

但是我不希望这样做.我在通用存储库中喜欢的是,它使我不必对所有不同的表重复使用相同的代码(我有300多个).但是拥有BaseEntity也将意味着对我已经完成的工作进行大量重组. 是否可以有一个通用回购协议,您可以在没有此BaseEntity类的情况下将其应用于任何POCO?

But I don't want to do this ideally. What I like in the generic repo is that it allows me to not repeat the same code for all the different tables (I have 300+). But having a BaseEntity would also mean restructuring alot of what I have already done. Is it possible to have a Generic repo that you can apply on any POCO without this BaseEntity class?

感谢您的帮助

推荐答案

您正在呼叫第二个参数的类型为Expression<Func<T, bool>>,因此您可以根据需要使用标识符属性来手动构建表达式.

Its second parameter has the type Expression<Func<T, bool>> so you can build expression manually, using as identifier property as you wish.

简短示例:

public T Get(long id)
{
    var idName = "ID" + typeof(T).Name; // For Document would be IDDocument
    var parameter = Expression.Parameter(id.GetType());
    var property = Expression.Property(parameter, idName)
    var idValue = Expression.Constant(id, id.GetType());
    var equal = Expression.Equal(property, idValue);
    var predicate = Expression.Lambda<Func<T, bool>>(equal, parameter);
    return entities.SingleOrDefault(predicate);
}

想象一下您编写了lambda函数(T obj) => obj.IdProperty == id. 这里objparameter,并且idName应该存储"IdProperty"字符串. property表示obj.IdPropertyidValue表示id的值. equal表示obj.IdProperty == id,谓词表示整个表达式(T obj) => obj.IdProperty == id.

Imagine you wrote lambda function (T obj) => obj.IdProperty == id. Here obj is parameter, and idName should store "IdProperty" string. property means obj.IdProperty, idValue means the value if id. equal means obj.IdProperty == id, and predicate means whole expression (T obj) => obj.IdProperty == id.

这篇关于通用存储库是否需要将基础实体类应用于任何地方?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆