通用 Table 加入 Entity Framework
Generic Table Join in Entity Framework
我正在尝试创建一个通用方法,它将连接两个 table 并通过提供谓词来过滤它们。谓词需要是动态的,因为在我的应用程序中每个用户角色都会不同。因此,例如,一个角色应该看到特定的状态和日期,而另一个角色可能需要不同日期的数据。
我发现的唯一相似之处是以下代码,它仅在单个 table 中运行提供的通用谓词以对其进行过滤。所以我想我应该使用类似的东西
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;
}
我需要提供我想要加入的 table 和一个组合谓词,用于过滤来自两个 table 的数据以及我想要 return 的数据类型。也许像下面这样。我想是这样的
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);
}
当然,您可以更改谓词以便根据需要动态过滤数据
我正在尝试创建一个通用方法,它将连接两个 table 并通过提供谓词来过滤它们。谓词需要是动态的,因为在我的应用程序中每个用户角色都会不同。因此,例如,一个角色应该看到特定的状态和日期,而另一个角色可能需要不同日期的数据。
我发现的唯一相似之处是以下代码,它仅在单个 table 中运行提供的通用谓词以对其进行过滤。所以我想我应该使用类似的东西
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;
}
我需要提供我想要加入的 table 和一个组合谓词,用于过滤来自两个 table 的数据以及我想要 return 的数据类型。也许像下面这样。我想是这样的
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);
}
当然,您可以更改谓词以便根据需要动态过滤数据