繁体   English   中英

实体框架中的通用表连接

[英]Generic Table Join in Entity Framework

我正在尝试创建一个通用方法,它将连接两个表并通过提供谓词来过滤它们。 谓词需要是动态的,因为在我的应用程序中每个用户角色都会有所不同。 因此,例如,一个角色应该查看特定的状态和日期,而另一个角色可能需要查看不同日期的数据。

我发现的唯一类似的事情是以下代码,它只是在单个表中运行提供的通用谓词来过滤它。 所以我想我应该使用类似的东西

public IEnumerable<T> Get_Data<T>(Expression<Func<T, bool>> predicate) where T : class
{
     IEnumerable<T> items = null;
     items = this.DbContext.Set<T>().Where(predicate);
     return items;
}

我需要提供我想要加入的表和一个组合谓词,用于过滤两个表中的数据以及我想要返回的数据类型。 可能像下面这样。 我认为类似于以下内容

    public IEnumerable<Action> Get_Data<T1,T2>(
        Expression<Func<T1,T2,bool>> filterPredicate, 
        Expression<Func<T1, T2, bool>> joinPredicate) 
            where T1 : class
            where T2 : class
    {
        IEnumerable<Action> items = null;
       //join tables and filter them by using the predicate using linq
        return items;
    }

在四处寻找之后,这就是我想出的。 假设我们有两个上下文实体用户和角色,我们想要加入和过滤

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

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

使用所有必需的表达式创建一个 class。 这包含将过滤数据的谓词和将用于连接表的键

    public class Expressions_BO<TObj, TBase>
    {
        public Expression<Func<TObj, bool>> Child_Predicate { get; set; }
        public Expression<Func<TObj, decimal>> Child_Key { get; set; }
        public Expression<Func<TBase, bool>> Base_Predicate { get; set; }
        public Expression<Func<TBase, decimal>> Base_DS_Key { get; set; }
    }

我创建了将加入和过滤数据的通用方法

    public static IEnumerable<Users_With_Roles> Get_Data<TObj, TBase>(Expressions_BO<TObj, TBase> filter_Grid) where TObj : class where TBase : class
    {
        var roles_ctx = this.DbContext.Set<TObj>();
        var users_ctx = this.DbContext.Set<TBase>();
        var source = users_ctx
          .Where(filter_Grid.Base_Predicate)
          .Join(roles_ctx.Where(filter_Grid.Child_Predicate), filter_Grid.Base_DS_Key, filter_Grid.Child_Key,
            (user, role) => new
            {

            });
        return source;
    }

然后,如果我想使用它,我可以这样称呼它

    static void Main(string[] args)
    {
        var grid_Filters = new Expressions_BO<Roles, Users>()
        {
            //Any predicate you want. I am just using a default always true just for this example
            Child_Predicate = (x) => true,
            Base_Predicate = (x) => true,
            //Dealslip Base Key
            Base_DS_Key = (x) => x.ID,
            //Dealslip Key
            Child_Key = (x) => x.ID
        };

        Get_Data(grid_Filters);
    }

当然,您可以更改谓词以便根据需要动态过滤数据

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM