【发布时间】:2013-11-22 08:57:01
【问题描述】:
我想存储一组访问对象属性的表达式。例如:
class Entity
{
public int Id { get; set; }
public Entity Parent { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public decimal Value { get; set; }
public bool Active { get; set; }
}
static void Main(string[] args)
{
var list = new List<Expression<Func<Entity, object>>>();
list.Add(e => e.Id);
list.Add(e => e.Name);
list.Add(e => e.Parent);
list.Add(e => e.Date);
list.Add(e => e.Value);
list.Add(e => e.Active);
StringBuilder b = new StringBuilder();
list.ForEach(f => b.AppendLine(f.ToString()));
Console.WriteLine(b.ToString());
Console.ReadLine();
}
这段代码输出:
e => Convert(e.Id)
e => e.Name
e => e.Parent
e => Convert(e.Date)
e => Convert(e.Value)
e => Convert(e.Active)
它确实将Convert 添加到值类型。
至于最终我想将这些表达式与 LINQ to SQL 一起使用,我不需要在表达式中包含 Convert,以便将它们成功转换为 SQL。
我怎样才能做到这一点?
P.S.:此集合中的表达式稍后用作 OrderBy 和 ThenBy 方法的参数。
【问题讨论】:
-
Convert在那里有什么害处?如果要对值类型进行装箱(如果要编译表达式),则隐式需要Convert操作。或者你只是在获得表达式的字符串表示之后?一种选择是通过在Expression<S, T>周围创建一个包装器类(如Wrapper<S>)使其完全通用,并将包装器添加到列表而不是表达式本身。这行得通吗? -
@nawfal 我想
Convert出现在那里是由于Func签名,因为它应该返回object,并且它确实尝试将值装箱。在一个真正的应用程序中,我确实有一个表达式集合,就像 OP 中描述的那样。它们实际上用于OrderBy和ThenBy与LINQ to SQLIQuerable<Entity>。所以我得到一个例外,说,它未能通过object订购 -
这是个好问题。你只关心 OrderBy 和 ThenBy 吗?还是您希望它用于一大堆查询方法?
-
您想要的动态 Linq 功能,并且已经有一些库可用(您可以进行搜索)。但我在这里建议的是anthony's answer here。基本上思路和我之前评论中提到的一样,备份包装器而不是表达式本身,然后将做Linq操作的任务委托给类本身。但是,如果您需要负担更多的方法,那就需要更多的工作。稍后我会尝试提供答案。
-
@nawfal 谢谢。我会尽快考虑清楚,然后写在这里。
标签: c# generics linq-to-sql expression