简体   繁体   English

实体框架中的通用表连接

[英]Generic Table Join in Entity Framework

I am tryng to create a generic method that will join two tables and filter them by providing a predicate.我正在尝试创建一个通用方法,它将连接两个表并通过提供谓词来过滤它们。 The predicate needs to be dynamic because it will be different per user role in my application.谓词需要是动态的,因为在我的应用程序中每个用户角色都会有所不同。 So for example one role should see specific statuses and dates and another one might need to data for different dates.因此,例如,一个角色应该查看特定的状态和日期,而另一个角色可能需要查看不同日期的数据。

The only similar thing I have found is the following code which just runs a provided generic predicate in a single table to filter it.我发现的唯一类似的事情是以下代码,它只是在单个表中运行提供的通用谓词来过滤它。 So i guess i should use something similar to it所以我想我应该使用类似的东西

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;
}

I need to provide the tables I want to join and a combining predicate for filtering data from both tables with the type of data i want to return.我需要提供我想要加入的表和一个组合谓词,用于过滤两个表中的数据以及我想要返回的数据类型。 Like the following maybe.可能像下面这样。 I think something like the following我认为类似于以下内容

    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;
    }

After searching around this is what I came up with.在四处寻找之后,这就是我想出的。 Let's say we have two context entities users and roles which we want to join and filter假设我们有两个上下文实体用户和角色,我们想要加入和过滤

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

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

Create a class with all the required expressions.使用所有必需的表达式创建一个 class。 This contains the predicates which will filter the data and the keys that will be used for joining the tables这包含将过滤数据的谓词和将用于连接表的键

    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; }
    }

I create the generic method that will join and filter the data我创建了将加入和过滤数据的通用方法

    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;
    }

Then if i want to use this I can call it like this然后,如果我想使用它,我可以这样称呼它

    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);
    }

Off course you can change the predicates in order to filter the data dynamically as you wish当然,您可以更改谓词以便根据需要动态过滤数据

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

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