我得到了这个测试:
[Fact]
public void EverythingIsMappedJustFine(){
new AutoMapperTask().Execute();
Mapper.AssertConfigurationIsValid();
}
Run Code Online (Sandbox Code Playgroud)
它引发了一个奇怪的异常:
测试"Unit.Web.Bootstrap.AutoMapperFacts.EverythingIsMappedJustFine"失败:
System.InvalidOperationException:没有强制经营者被定义
类型"System.Void"和"System.Object的"之间.
在System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType,表达式表达,类型convertToType)
...
在AutoMapper.DelegateFactory.CreateGet(MethodInfo的方法)
不幸的是 - 我无法在较小规模上重现这一点,也无法弄清楚到底发生了什么.
什么是强制运营商?
这可能很有用.但我没有提取和愚弄必要的信息位.
我有两个表达式在不同的时间构建,但需要合并才能获得where子句的准确"分组".我确实尝试过这个选项,但是我使用的是实体框架而且它不了解这个Invoke功能.我已经看到了一些ExpressionVisitor替代方案,但我不认为我对我需要做的事情有足够的了解.
如果有人能指出我正确的方向,我会非常感激,感觉它就在那里.
条款1A (对象类型Expression<Func<T, bool>>)
{parm => parm.Name.Contains("hat")}
Run Code Online (Sandbox Code Playgroud)
条款1B (对象类型LambdaExpression,但可以使用(Expression<Func<T, bool>>)LambdaExpression)
{parm => parm.Attributes.Any(parm => ((parm.Name == "test") AndAlso (parm.Value == "21")))}
Run Code Online (Sandbox Code Playgroud)
条款需要
{parm =>
parm.Name.Contains("hat") (&&/||)
parm.Attributes.Any(parm => ((parm.Name == "test") AndAlso (parm.Value == "21")))
}
Run Code Online (Sandbox Code Playgroud)
如果有人可以帮我合并第1A条和第1B条,我会非常感谢..
只是一个FYI Where()和Any()子句是从IQueryable获得的泛型方法,不确定是否重要.
Func<MethodInfo, bool> methodLambda = m => m.Name == "Any" && m.GetParameters().Length == 2;
MethodInfo method = typeof(Queryable).GetMethods().Where(methodLambda).Single().MakeGenericMethod(ActualQueryableType);
ParameterExpression parentMember = Expression.Parameter(typeof(T), "parentParm");
// Create …Run Code Online (Sandbox Code Playgroud) 在那里,我只看到最新的LINQKit版本依赖于EF 6.0.2,我需要在EF 5.0上安装,是否有一个较旧的LINQKit版本兼容EF 5.0?或其他东西来替换它(.Expand()功能)?
这是在数据层上,因此性能非常重要。否则我会使用 Automapper。如果它是 IDBConnection,我会使用 Dapper。
我想将匿名对象的简单创作带到 POCO 并使用编译表达式表达它。
代码
public class Foo
{
public string Bar{get;set;}
public string Baz{get;set;}
}
public void doStuff()
{
var obj = new{Bar= "My Name, Baz = "Some other data"};
//can I recreate this assignment to foo using expressions?
var foo = new Foo{
Bar = obj.Bar,
Baz = obj.Baz
}
}
Run Code Online (Sandbox Code Playgroud)
(未完成)到目前为止,我已经...
var props = o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
foreach (var prop in props)
{
var targetProp = typeof(T).GetProperty(prop.Name);
var targetExp = Expression.Parameter(typeof(T), "target"); …Run Code Online (Sandbox Code Playgroud) 我正在重构一些代码,试图使其更具自我记录性。当前代码对 OData 服务进行了查询,如下所示:
return context.MessageLog.Where
(
x =>
(
x.Status == MessageStatus.Success
|| x.Status == MessageStatus.Failure
)
&& x.Direction == MessageDirection.Inbound
&& x.ResponseDate == new DateTimeOffset(new DateTime(1900, 01, 01))
);
Run Code Online (Sandbox Code Playgroud)
我希望改变这一点以利用 Linq 表达式。
我可以将所有逻辑移动到单个表达式中并运行代码context.MessageLog.Where(MessageIsPendingResponse);。但是,我想为不同的条件创建表达式:(MessageIsProcessed即现在处于成功或失败状态)MessageIsInbound和ResponseNotYetSent(响应日期为空)。我可以将这些与多个 where 语句结合起来,如下所示:
return context.MessageLog
.Where(MessageLogExpression.MessageIsProcessed)
.Where(MessageLogExpression.MessageIsInbound)
.Where(MessageLogExpression.ResponseNotYetSent);
Run Code Online (Sandbox Code Playgroud)
(MessageLogExpression作为我用来包含这些预定义表达式的类)。
这是组合语句的最佳方式,还是先过滤错误字段的风险(例如,Linq 是否将所有条件组合成单个查询并允许查询引擎(在 SQL 术语中)确定最佳执行计划;或我们是否强制它首先过滤状态字段?
以上对于我们AND加入表达式的场景非常有用;但是我们怎么做OR呢?我认为有一些方法可以将这些结合起来,但找不到任何明显的东西。我怀疑这样的事情存在吗?
return context.MessageLog.Where(new OrExpression(MessageIsSuccess,MessageIsFailure));
Run Code Online (Sandbox Code Playgroud)
是否有一种在另一个表达式定义中组合表达式的好方法;例如像下面的代码(只有一个编译版本)?
public static Expression<Func<MessageLogRecord, bool>> MessageIsPendingResponse
{
get
{
Expression<Func<MessageLogRecord, bool>> …Run Code Online (Sandbox Code Playgroud) TLDR:这是如何编译的?
class A{};
Expression<Func<A, int>> e = x => 24; // I don't understant what makes this compile
// and what happens at this assignment
Run Code Online (Sandbox Code Playgroud)
最少要多少class E才能编译E e = x => 24;
一些调查
class E {};
E e = x => 24;
Run Code Online (Sandbox Code Playgroud)
Visual Studio 错误是“无法将 lambda 表达式转换为类型 'E',因为它不是委托类型”,这很令人困惑,因为据我所知,委托是这样声明的:
int delegate MyHandle();
Run Code Online (Sandbox Code Playgroud)
我没有找到任何任命class代表的方法。
此外,我查看了元数据Expression -> LambdaExpression -> Expression<TDelegate>,但无法确定哪些语法/声明使Expression<TDelegate>行为像委托一样。
我什至尝试创建自己的class E来模仿Expression<TDelegate>,但我什至无法编译该类
// basically a copy-paste of the metadata of …Run Code Online (Sandbox Code Playgroud) 我刚输入以下代码:
Expression<Func<ContentItem, bool>> expression =
fileTypeGroupID.HasValue ? n => n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value : n => true;
Run Code Online (Sandbox Code Playgroud)
Visual Studio说它不能推断出它的类型n.
代码对我来说似乎很好 - 它只是使用三元运算符将两个Expression文字中的一个分配给Expression变量.
Visual Studio是不是很聪明,不能推断出n三元运算符内部的类型,还是我犯了某种错误?
我想验证我的假设,即LINQ Expression API没有任何方法可以让我们创建一个表示局部变量创建的表达式.
换句话说,您无法创建表达式来表示:
int local;
Run Code Online (Sandbox Code Playgroud)
因为那是一个变量声明语句,并且API不支持语句lambdas.lambda表达式(由LINQ表达式API(而不是委托实例)表示)可以使用的唯一状态是它接收的参数以及它通过闭包接收的捕获变量.
我的假设(基于几个月的LINQ Expression API实践)是否正确?
假设我们有以下正则表达式:
var result = SomeList.Where(item => item.Status.Description.Contains("READY"));
Run Code Online (Sandbox Code Playgroud)
对于这些对象:
public class Movie
{
public MovieStatus Status {get; set;}
}
public class MovieStatus
{
public string Description {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用:
ParameterExpression pe = Expression.Parameter(typeof(T), "item.Status");
MemberExpression propExp = Expression.Property(pe, "Description");//boem! Description is not a property of T.
Run Code Online (Sandbox Code Playgroud)
通过T属性的一些递归,我可以获得正确的信息,MemberExpression并且在调试时看起来还不错,最后我有了以下lambda表达式:
{item => item.Status.Description.Contains(“ READY”)}
并且,将这些表达式应用于IQueryable列表时,将是以下结果:
{System.Collections.Generic.List`1 [Movie] .Where(item => item.Status.Description.Contains(“ READY”))}
看起来不错,但是当编译/执行列表中的表达式时,它给了我以下错误:
附加信息:从范围''引用的类型为'MovieStatus'的变量'item.Status',但未定义
我如何需要“链接” ParameterExpression到以获得上面的lambda表达式?
真正的代码没有这些固定变量,它是具有任何子属性的任何对象都可以使用的通用实现。输入的是标准格式XX.YY的属性名称,以及一个比较值。发布所有代码有点大,但是下面是其中的一部分,删除了所有递归以关注问题。递归的一些结果已在此处进行了硬编码。此外,并非总是如此Contains。
public static void Test<T>(IQueryable<T> source)
{
string propertyName …Run Code Online (Sandbox Code Playgroud) 我有一个通用方法,我想IQueryable<T>按其关键字段对它进行排序(可以放心地假设只有一个)。从而:
void DoStuff<T>(...)
{
IQueryable<T> queryable = ... // given
PropertyInfo keyField = ... // given
var sortedQueryable = queryable.OrderBy(<some expression here>);
...
}
Run Code Online (Sandbox Code Playgroud)
我如何定义一个Expression将返回keyField属性的T,这样才能正常工作?
linq-expressions ×10
c# ×9
linq ×7
expression ×2
lambda ×2
automapper ×1
delegates ×1
linqkit ×1
moq ×1
odata ×1
recursion ×1