它们是一样的吗?刚看完Rob Connery的店面教程,他们似乎是类似的技术.我的意思是,当我实现一个DAL对象时,我有GetStuff,Add/Delete等方法,我总是首先编写接口,这样我以后就可以切换db了.
我混淆了什么吗?
给定这样的类结构:
public class GrandParent
{
public Parent Parent { get; set;}
}
public class Parent
{
public Child Child { get; set;}
}
public class Child
{
public string Name { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
和以下方法签名:
Expression<Func<TOuter, TInner>> Combine (Expression<Func<TOuter, TMiddle>>> first, Expression<Func<TMiddle, TInner>> second);
Run Code Online (Sandbox Code Playgroud)
我如何实现所述方法,以便我可以像这样调用它:
Expression<Func<GrandParent, Parent>>> myFirst = gp => gp.Parent;
Expression<Func<Parent, string>> mySecond = p => p.Child.Name;
Expression<Func<GrandParent, string>> output = Combine(myFirst, mySecond);
Run Code Online (Sandbox Code Playgroud)
这样输出结果如下:
gp => gp.Parent.Child.Name
Run Code Online (Sandbox Code Playgroud)
这可能吗?
每个Func的内容只会是一个MemberAccess.我宁愿不最终output成为嵌套函数调用.
谢谢
我正在尝试创建一个通用函数来帮助我从本地列表中使用LINQ to SQL选择数千条记录.SQL Server(至少2005)将查询限制为2100个参数,我想选择更多的记录.
这将是一个很好的示例用法:
var some_product_numbers = new int[] { 1,2,3 ... 9999 };
Products.SelectByParameterList(some_product_numbers, p => p.ProductNumber);
Run Code Online (Sandbox Code Playgroud)
这是我的(非工作)实现:
public static IEnumerable<T> SelectByParameterList<T, PropertyType>(Table<T> items,
IEnumerable<PropertyType> parameterList, Expression<Func<T, PropertyType>> property) where T : class
{
var groups = parameterList
.Select((Parameter, index) =>
new
{
GroupID = index / 2000, //2000 parameters per request
Parameter
}
)
.GroupBy(x => x.GroupID)
.AsEnumerable();
var results = groups
.Select(g => new { Group = g, Parameters = g.Select(x => x.Parameter) } )
.SelectMany(g …Run Code Online (Sandbox Code Playgroud) 我有一个包含多个字段的表单(公司名称,邮政编码等),允许用户搜索数据库中的公司.如果用户在多个字段中输入值,那么我需要搜索所有这些字段.我正在使用LINQ来查询数据库.
到目前为止,我已经设法编写了一个函数,它将查看它们的输入并将其转换为表达式列表.我现在想将该List转换为单个表达式,然后我可以通过LINQ提供程序执行该表达式.
我最初的尝试如下
private Expression<Func<Company, bool>> Combine(IList<Expression<Func<Company, bool>>> expressions)
{
if (expressions.Count == 0)
{
return null;
}
if (expressions.Count == 1)
{
return expressions[0];
}
Expression<Func<Company, bool>> combined = expressions[0];
expressions.Skip(1).ToList().ForEach(expr => combined = Expression.And(combined, expr));
return combined;
}
Run Code Online (Sandbox Code Playgroud)
但是,这会失败,并出现"二进制运算符并且未定义..."的异常消息.有没有人有任何想法,我需要做什么来结合这些表达式?
编辑:更正了我忘记将结果和表达式一起分配给变量的行.谢谢你指出那些人.
我需要对ObjectSet进行一些过滤,以通过这样做获取我需要的实体:
query = this.ObjectSet.Where(x => x.TypeId == 3); // this is just an example;
Run Code Online (Sandbox Code Playgroud)
稍后在代码中(以及在启动延迟执行之前)我再次过滤查询,如下所示:
query = query.Where(<another lambda here ...>);
Run Code Online (Sandbox Code Playgroud)
到目前为止,这很有效.
这是我的问题:
实体包含DateFrom属性和DateTo属性,它们都是DataTime类型.它们代表了一段时间.
我需要过滤的实体只拿到那些一个部分集合的时间段.集合中的句点不一定是连续的,因此,检索实体的逻辑看起来像这样:
entities.Where(x => x.DateFrom >= Period1.DateFrom and x.DateTo <= Period1.DateTo)
||
entities.Where(x => x.DateFrom >= Period2.DateFrom and x.DateTo <= Period2.DateTo)
||
Run Code Online (Sandbox Code Playgroud)
......以及集合中所有时期的不断变化.
我试过这样做:
foreach (var ratePeriod in ratePeriods)
{
var period = ratePeriod;
query = query.Where(de =>
de.Date >= period.DateFrom …Run Code Online (Sandbox Code Playgroud) 我有以下查询:
db.Users.AsQueryable()
.Where(u => u.Id = userResolver.LoggedUserId() && u.Packages.Where(p =>
p.StatusId == (int)PackageStatus.InProgress ||
p.StatusId == (int)PackageStatus.Delivered ||
p.StatusId == (int)PackageStatus.Shipped ||
p.StatusId == (int)PackageStatus.Waiting)
.Sum(p => p.Price) > u.MaxCredit)
.ToList()
Run Code Online (Sandbox Code Playgroud)
我想要实现的目标是将所有包状态检查分组到扩展方法中。像这样的东西:
db.Users.AsQueryable()
.Where(u => u.Id = userResolver.LoggedUserId() &&
u.Packages.Where(p => p.IsShippedOrInProgress())
.Sum(p => p.Price) > u.MaxCredit)
.ToList()
//This is the extension method
public static bool IsShippedOrInProgress(this Package p) {
return p.StatusId == (int)PackageStatus.InProgress ||
p.StatusId == (int)PackageStatus.Delivered ||
p.StatusId == (int)PackageStatus.Shipped ||
p.StatusId == (int)PackageStatus.Waiting)
}
Run Code Online (Sandbox Code Playgroud)
当我查看第一个示例中生成的 sql 查询时,一切似乎都正常,但是当我使用第二种方法时,检查状态的查询部分不存在。
我找不到从Expression <Func <T1,bool >>转换为Expression <Func <T2,bool >>的方法.因为我使用了大量的反射,实际上,我真正需要的是一种采用类型参数并执行转换的方法.
public object Convert(Expression<Func<T1,bool>> expr, Type t);
Run Code Online (Sandbox Code Playgroud)
T2来自T1
public class T1 {
int FamilyId {get; set;}
}
public class T2 : T1 {
... other properties
}
Run Code Online (Sandbox Code Playgroud)
我在基类上定义了一个过滤器表达式
Expression<Func<T1,bool>> filter = p => p.FamilyId == [some value]
Run Code Online (Sandbox Code Playgroud)
我想申请List <T2>
我有3个谓词,我想要AndAlso介于两者之间.我在板上发现了几个样本,但无法解决我的问题.
这些谓词是: Expression<Func<T, bool>>
我有这个代码:
Expression<Func<T, bool>> predicate1 = ......;
Expression<Func<T, bool>> predicate2 = ......;
Expression<Func<T, bool>> predicate3 = ......;
Run Code Online (Sandbox Code Playgroud)
我创建了一个扩展方法来创建一个"AndAlso":
public static Expression<Func<T, bool>> AndAlso<T>(
this Expression<Func<T, bool>> expr,
Expression<Func<T, bool>> exprAdd)
{
var param = Expression.Parameter(typeof(T), "p");
var predicateBody = Expression.AndAlso(expr.Body, exprAdd.Body);
return Expression.Lambda<Func<T, bool>>(predicateBody, param);
//Tried this too
//var body = Expression.AndAlso(expr.Body, exprAdd.Body);
//return Expression.Lambda<Func<T, bool>>(body, expr.Parameters[0]);
}
Run Code Online (Sandbox Code Playgroud)
我用这样的:
var finalPredicate = predicate1
.AndAlso<MyClass>(predicate2)
.AndAlso<MyClass>(predicate3);
Run Code Online (Sandbox Code Playgroud)
谓词看起来像这样:

当我在查询中使用时:
var res = myListAsQueryable().Where(finalPredicate).ToList<MyClass>();
Run Code Online (Sandbox Code Playgroud)
我得到这个错误: 从范围''引用的'BuilderPredicate.MyClass'类型的变量'p',但它没有定义
你能告诉我什么是错的吗?
非常感谢,
我有一个方法接受一个Expression<Func<bool>>参数
void MethodOne(Expression<Func<bool>> expression)
Run Code Online (Sandbox Code Playgroud)
我有多个实例Expression<Func<bool>>.如何动态地将这些表达成一个单一的Expression<Func<bool>>使用Expression.OrElse(即建立一个表达式树)?
例如,如果我有两个表达式,如
() => objectA.PropertyOneIsSet
Run Code Online (Sandbox Code Playgroud)
和
() => objectB.PropertyTwoIsSet
Run Code Online (Sandbox Code Playgroud)
我希望最终结果是:
() => objectA.PropertyOneIsSet || objectB.PropertyTwoIsSet
Run Code Online (Sandbox Code Playgroud)
所以我可以将它传递给我上面的方法.
我有一个现有的lambda-expression,其创建方式如下:
Expression<Func<Entities.Area, bool>> where = (x => (x.Created > this.Value || (x.Changed != null && x.Changed > this.Value)));
Run Code Online (Sandbox Code Playgroud)
现在,我必须用以下表达式扩展此表达式:
Expression<Func<Entities.Area, bool>> whereAdd = (x => x.Client.Id == ClientInfo.CurrentClient.Id);
Run Code Online (Sandbox Code Playgroud)
结果应类似于:
Expression<Func<Entities.Area, bool>> where = (x => (x.Created > this.Value || (x.Changed != null && x.Changed > this.Value)) && x.Client.Id == ClientInfo.CurrentClient.Id);
Run Code Online (Sandbox Code Playgroud)
我不能直接更改第一个表达式的创建,因为它不是我的代码。
我希望有人能帮助我扩展第一个lambda表达式。