如何使用 where 子句表达式在查询中加入实体 Framework/Linq
How to do Entity Framework/Linq join in query with where clause expressions
我有一个 Entity Framework 查询,其中 where 子句的变化基于多个选择。
这是我的代码:
Expression<Func<CtCsGroup, bool>> where_expression1 = x => 1 == 1;
Expression<Func<CtCsGroup, bool>> where_expression2 = x => 1 == 1;
Expression<Func<CtCsGroup, bool>> where_expression3 = x => 1 == 1;
if (selections.SearchCSGroup.NoNull() != "")
{
where_expression1 = x => x.CsGroup.ToUpper() == selections.SearchCSGroup.ToUpper();
}
if (selections.SearchUserId.NoNull() != "")
{
where_expression3 = x => x.UsrIdn.ToUpper() == selections.SearchUserId.ToUpper();
}
if (!selections.SearchIncludeRetires)
{
where_expression2 = x => x.CsRetire != "Y";
}
var groupDTOs = (from g in _infobaseContext.CtCsGroup
.Where(where_expression1)
.Where(where_expression2)
.Where(where_expression3)
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" // n.CsGroupName
}).ToList();
我想添加一个连接到另一个 table。
如何将其添加到上述查询中?我尝试了几种不同的格式,但每当我添加它时,我都会收到错误 "(where_expression1)" ,"(where_expression3)" 等
谢谢。
这里有更多详细信息...
var groupDTOs = (from g in _infobaseContext.CtCsGroup
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = n.CsGroupName
}).ToList();
- 而这一个在没有连接的情况下工作 -
var groupDTOs = (from g in _infobaseContext.CtCsGroup
.Where(where_expression1)
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" //n.CsGroupName
}).ToList();
- 但是当我同时添加连接和表达式时 -
var groupDTOs = (from g in _infobaseContext.CtCsGroup
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup
.Where(where_expression1)
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = n.CsGroupName
}).ToList();
- Visual Studio 给出了这个错误:
参数 2:无法从 'System.Linq.Expressions<System.Func<IBDataServices.Models.CtCsGroup, bool>>' 转换为 'System.Func<char,bool>'
通常我们会努力通过多个步骤组合查询,而不是尝试注入多个 pre-composed 谓词。您已经在使用 Fluent 表示法来应用谓词,因此将该过程从基于 Query 的表达式中分离出来。
您还会注意到比较值已被参数化,而不是让 linq 解释器 为我们决定什么是查询引用以及什么是离散值或标量值。
You haven't posted the specific errors, however where the linq expression is being evaluated it the elections.SearchCSGroup
is probably out of scope and cannot be resolved. Deliberate parameterization avoids this confusion.
IQueryable<CtCsGroup> groupQuery = _infobaseContext.CtCsGroup;
if (selections.SearchCSGroup.NoNull() != "")
{
// Force the comparison against a discrete parameter value
var selection = selections.SearchCSGroup.ToUpper();
groupQuery = groupQuery.Where(x => x.CsGroup.ToUpper() == selection);
}
if (selections.SearchUserId.NoNull() != "")
{
var selection = selections.SearchUserId.ToUpper();
groupQuery = groupQuery.Where(x => x.UsrIdn.ToUpper() == selection);
}
if (!selections.SearchIncludeRetires)
{
// NOTE: "Y" will be correctly interpreted as a discrete parameter value
groupQuery = groupQuery.Where(x => x.CsRetire != "Y");
}
var groupDTOs = (from g in groupQuery
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" // n.CsGroupName
}).ToList();
最后一部分也可以组成 fluent 表达式,而不是基于 query 的表达式:
var groupDTOs = groupQuery.Select(g => new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" // n.CsGroupName
}).ToList();
此模式可帮助您避免首先尝试通过 pre-compiled 谓词引起的这些问题,尤其是它消除了使用不正确的类型绑定定义谓词的可能性。
此模式也有助于编写具有条件排序列或方向的表达式。
您发布的最后一期是红鲱鱼,您混淆了语法,该表达式本来就没有用。
Visual Studio is giving this error: Argument 2: cannont convert from 'System.Linq.Expressions<System.Func<IBDataServices.Models.CtCsGroup, bool>>' to 'System.Func<char,bool>'
具体这一段:
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup.Where(where_expression1)
你现在可能会看到它,因为换行符被删除了,n.CsGroup
是一个字符串,它本身 IEnumerable<char>
所以它假设你想将 where_expression1
谓词应用到n.CsGroup
的值
我们仍然可以使用普通的 linq 连接表达式连接到组合查询:
var groupDTOs = (from g in groupQuery
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = n.CsGroupName
}).ToList();
如果您的架构在 CtCsGroup
上有一个名为 CsGroup
的导航 属性,它表示 TblCsGroupList
和 CtCsGroup
之间的关系,那么我们可以使用 点符号和必要的连接将是隐式的。
NOTE: This makes broad assumptions about the schema and is only included to show a common structural alternative to manually defining joins
var groupDTOs = (from g in groupQuery
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = g.CsGroup.CsGroupName
}).ToList();
我有一个 Entity Framework 查询,其中 where 子句的变化基于多个选择。
这是我的代码:
Expression<Func<CtCsGroup, bool>> where_expression1 = x => 1 == 1;
Expression<Func<CtCsGroup, bool>> where_expression2 = x => 1 == 1;
Expression<Func<CtCsGroup, bool>> where_expression3 = x => 1 == 1;
if (selections.SearchCSGroup.NoNull() != "")
{
where_expression1 = x => x.CsGroup.ToUpper() == selections.SearchCSGroup.ToUpper();
}
if (selections.SearchUserId.NoNull() != "")
{
where_expression3 = x => x.UsrIdn.ToUpper() == selections.SearchUserId.ToUpper();
}
if (!selections.SearchIncludeRetires)
{
where_expression2 = x => x.CsRetire != "Y";
}
var groupDTOs = (from g in _infobaseContext.CtCsGroup
.Where(where_expression1)
.Where(where_expression2)
.Where(where_expression3)
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" // n.CsGroupName
}).ToList();
我想添加一个连接到另一个 table。
如何将其添加到上述查询中?我尝试了几种不同的格式,但每当我添加它时,我都会收到错误 "(where_expression1)" ,"(where_expression3)" 等
谢谢。
这里有更多详细信息...
var groupDTOs = (from g in _infobaseContext.CtCsGroup
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = n.CsGroupName
}).ToList();
- 而这一个在没有连接的情况下工作 -
var groupDTOs = (from g in _infobaseContext.CtCsGroup
.Where(where_expression1)
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" //n.CsGroupName
}).ToList();
- 但是当我同时添加连接和表达式时 -
var groupDTOs = (from g in _infobaseContext.CtCsGroup
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup
.Where(where_expression1)
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = n.CsGroupName
}).ToList();
- Visual Studio 给出了这个错误:
参数 2:无法从 'System.Linq.Expressions<System.Func<IBDataServices.Models.CtCsGroup, bool>>' 转换为 'System.Func<char,bool>'
通常我们会努力通过多个步骤组合查询,而不是尝试注入多个 pre-composed 谓词。您已经在使用 Fluent 表示法来应用谓词,因此将该过程从基于 Query 的表达式中分离出来。
您还会注意到比较值已被参数化,而不是让 linq 解释器 为我们决定什么是查询引用以及什么是离散值或标量值。
You haven't posted the specific errors, however where the linq expression is being evaluated it the
elections.SearchCSGroup
is probably out of scope and cannot be resolved. Deliberate parameterization avoids this confusion.
IQueryable<CtCsGroup> groupQuery = _infobaseContext.CtCsGroup;
if (selections.SearchCSGroup.NoNull() != "")
{
// Force the comparison against a discrete parameter value
var selection = selections.SearchCSGroup.ToUpper();
groupQuery = groupQuery.Where(x => x.CsGroup.ToUpper() == selection);
}
if (selections.SearchUserId.NoNull() != "")
{
var selection = selections.SearchUserId.ToUpper();
groupQuery = groupQuery.Where(x => x.UsrIdn.ToUpper() == selection);
}
if (!selections.SearchIncludeRetires)
{
// NOTE: "Y" will be correctly interpreted as a discrete parameter value
groupQuery = groupQuery.Where(x => x.CsRetire != "Y");
}
var groupDTOs = (from g in groupQuery
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" // n.CsGroupName
}).ToList();
最后一部分也可以组成 fluent 表达式,而不是基于 query 的表达式:
var groupDTOs = groupQuery.Select(g => new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = "test" // n.CsGroupName
}).ToList();
此模式可帮助您避免首先尝试通过 pre-compiled 谓词引起的这些问题,尤其是它消除了使用不正确的类型绑定定义谓词的可能性。
此模式也有助于编写具有条件排序列或方向的表达式。
您发布的最后一期是红鲱鱼,您混淆了语法,该表达式本来就没有用。
Visual Studio is giving this error: Argument 2: cannont convert from 'System.Linq.Expressions<System.Func<IBDataServices.Models.CtCsGroup, bool>>' to 'System.Func<char,bool>'
具体这一段:
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup.Where(where_expression1)
你现在可能会看到它,因为换行符被删除了,n.CsGroup
是一个字符串,它本身 IEnumerable<char>
所以它假设你想将 where_expression1
谓词应用到n.CsGroup
我们仍然可以使用普通的 linq 连接表达式连接到组合查询:
var groupDTOs = (from g in groupQuery
join n in _infobaseContext.TblCsGroupList
on g.CsGroup equals n.CsGroup
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = n.CsGroupName
}).ToList();
如果您的架构在 CtCsGroup
上有一个名为 CsGroup
的导航 属性,它表示 TblCsGroupList
和 CtCsGroup
之间的关系,那么我们可以使用 点符号和必要的连接将是隐式的。
NOTE: This makes broad assumptions about the schema and is only included to show a common structural alternative to manually defining joins
var groupDTOs = (from g in groupQuery
select new
{
UsrIdn = g.UsrIdn,
CsGroup = g.CsGroup,
CsRetire = g.CsRetire,
CsGroupName = g.CsGroup.CsGroupName
}).ToList();