Общее объединение таблиц в Entity Framework - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь создать универсальный метод, который объединит две таблицы и отфильтрует их, предоставив предикат. Предикат должен быть динамическим, потому что он будет отличаться для каждой роли пользователя в моем приложении. Так, например, одна роль должна видеть определенные статусы и даты, а другая - данные для разных дат.

Единственное, что я обнаружил, - это следующий код, который просто запускает предоставленный общий предикат в одной таблице. отфильтровать это. Поэтому я думаю, что я должен использовать что-то похожее на это

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

1 Ответ

0 голосов
/ 18 октября 2019

После поисков вокруг это то, что я придумал. Допустим, у нас есть две контекстные сущности: пользователи и роли, к которым мы хотим присоединиться и отфильтровать

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

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

Создать класс со всеми необходимыми выражениями. Он содержит предикаты, которые будут фильтровать данные, и ключи, которые будут использоваться для объединения таблиц

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

Конечно, вы можете изменить предикаты, чтобы динамически фильтровать данные, как вы хотите

...