【问题标题】:Executing Expression ToLower on List throws exception在 List 上执行 Expression ToLower 会引发异常
【发布时间】:2013-06-19 16:06:28
【问题描述】:

我有以下代码:

public Expression FilterString(string property, string value, ParameterExpression parameter)
{
    //Create Message MemberExpression from parameter and properted eg/Message.Body
    var getname = Expression.Property(parameter, property);

    //Create expression for Not IsNullOrEmpty
    var isnullorempty = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, getname));

    //Create expression for member property equal to value eg/Message.Body = "hi"
    var toLower = Expression.Call(getname,
                         typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
    var compare = Expression.Equal(toLower, Expression.Constant(value));

    //Create expression combining Not IsNullOrEmpty AND Equal To
    var condition = Expression.And(isnullorempty, compare);

    return condition;
}

如果我运行下面的测试,我会得到一个NullReferenceException,我认为是因为某些项目的正文为空,但这正是Expression 应该测试的内容。

private IEnumerable<Message> GetMessages()
{
    var list = new List<Message>();

    var message = new Message() { Body = null, Properties = new Collection<MessageProperty>() };
    list.Add(message);

    message = new Message() { Body = "", Properties = new Collection<MessageProperty>() };
    list.Add(message);

    message = new Message() { Body = "Hello Everybody", Properties = new Collection<MessageProperty>() };
    list.Add(message);

    message = new Message() { Flag = 1, Properties = new Collection<MessageProperty>() };
    list.Add(message);

    message = new Message() { ChannelInt = 1,  Properties = new Collection<MessageProperty>() };
    list.Add(message);

    message = new Message() { Properties = new Collection<MessageProperty>(new[] { new MessageProperty() { Key = "Gender", Value = "male" } }) };
    list.Add(message);

    return list;
}

[Theory]
[InlineData("Hello Everybody")]
[InlineData("hello everybody")]
public void FilterString_NullAndEmptyMessages_Removed(string searchTerm)
{
    var messageList = GetMessages();

    var parameter = Expression.Parameter(typeof(Message), "message");

    var equalToFilterType = new EqualToFilterType();

    var filter = equalToFilterType.FilterString("Body", searchTerm, parameter);

    var lambda = Expression.Lambda(filter, parameter);

    //******EXCEPTION*******//
    var result = messageList.AsQueryable().Where((Expression<Func<Message, bool>>)lambda).ToList();

    Assert.Equal(1, result.Count);
}

有什么想法可以让我通过这个测试吗? (顺便说一句,我的表达式代码也将用于命中 SQL Server)

【问题讨论】:

  • 如果我的回答对您不起作用,如果您将其包装成一个简短但完整的控制台应用程序,我们可以自己测试,这将非常有帮助。

标签: c# .net linq linq-to-entities expression


【解决方案1】:

我怀疑这是问题所在:

var condition = Expression.And(isnullorempty, compare);

我怀疑你想要AndAlso

var condition = Expression.AndAlso(isnullorempty, compare);

实际上,现在你已经得到了

x & y

你想要的

x && y

【讨论】:

  • 好收获。按位 & 将执行这两个语句,而 && 将根据需要短路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 2012-02-28
  • 2018-11-06
  • 2021-08-09
相关资源
最近更新 更多