知乎周源微信_每周源代码48-DynamicQueryable使自定义LINQ表达式更容易

博客介绍了如何使用DynamicQueryable库和PredicateBuilder来简化动态生成的LINQ表达式,避免复杂的Expression树代码。作者分享了在不知道所有输入的情况下,如何通过动态查询提高代码的可读性和灵活性,特别提到了Marcin和ScottGu的建议以及提供的工具。
摘要由CSDN通过智能技术生成
知乎周源微信

知乎周源微信

NOTE: An alternative title to this post might be: "The Weekly Source Code 48: Making The Weekly Source Code 47 Suck Incrementally Less."

注意:此帖子的替代标题可能是:“每周源代码48:使每周源代码47逐渐减少。

NOTE: This isn't a language feature! This works on both C# and VB!

注意:这不是语言功能! 这适用于C#和VB!

Last week I wrote a post about Dynamic Linq Query Generation in order to solve a kind of meta-programming problem. I had a site that used ASP.NET Dynamic Data and I wanted to do a LINQ query against some data. However, because I was creating a template that didn't know enough at compile time to write a proper LINQ query that could, well, compile, I needed to creating my LINQ dynamically.

上周,我写了一篇有关动态Linq查询生成的文章,以解决一种元编程问题。 我有一个使用ASP.NET动态数据的网站,我想对某些数据进行LINQ查询。 但是,由于我创建的模板在编译时不够了解,无法编写可以编译的正确LINQ查询,因此需要动态创建LINQ。

Be sure to hang in here with me, the awesome happens at the end.

一定要和我一起住在这里,这真是太棒了。

I was trying to generate effectively this, at runtime

我试图在运行时有效地生成此

Items.Select(row => row.Property).Distinct.OrderBy(colvalue => colvalue)

And I succeeded with Tatham Oddie's help in doing it this sub-optimal way:

Tatham Oddie的帮助下,我以次优的方式成功做到了:

protected void Page_Init(object sender, EventArgs e) {
var items = Column.Table.GetQuery();
var entityParam = Expression.Parameter(Column.Table.EntityType, "row");

// row => row.Property
var columnLambda = Expression.Lambda(Expression.Property(entityParam, Column.EntityTypeProperty), entityParam);

// Items.Select(row => row.Property)
var selectCall = Expression.Call(typeof(Queryable), "Select", new Type[] { items.ElementType, columnLambda.Body.Type }, items.Expression, columnLambda);

// Items.Select(row => row.Property).Distinct
var distinctCall = Expression.Call(typeof(Queryable), "Distinct", new Type[] { Column.EntityTypeProperty.PropertyType }, selectCall);


// colvalue => colvalue
var sortParam = Expression.Parameter(Column.EntityTypeProperty.PropertyType, "sortValue");
var columnResultLambda = Expression.Lambda(sortParam, sortParam);

// Items.Select(row => row.Property).Distinct.OrderBy(colvalue => colvalue)
var ordercall = Expression.Call(typeof(Queryable), "OrderBy",
new Type[] { Column.EntityTypeProperty.PropertyType, columnResultLambda.Body.Type },
distinctCall, columnResultLambda);

var result = items.Provider.CreateQuery(ordercall);

foreach (var item in result) {
if (item != null) DropDownList1.Items.Add(item.ToString());
}
}

"Sub-optimal" is a programmer euphemism for crappy, hard to read, code that works. But what price my immortal soul?

“次优”是程序员的委婉说法,认为这些代码糟糕透了,难以阅读,并且有效。 但是我不朽的灵魂要付出什么代价呢?

Fortunately, Marcin from the ASP.NET team decided to come out of his apparent blogging vow of silence (lasting 18 months, no less) to save me.

幸运的是,来自ASP.NET团队的Marcin决定摆脱他明显的博客誓言(持续18个月,不少)以挽救我。

Marcin points out that there's a sample from 2006 released under the Ms-PL (how is anyone supposed to know this?) called DynamicQueryable. You actually have this on your hard drive NOW. It's under  Samples\1033\CSharpSamples.zip\LinqSamples\DynamicQuery\DynamicQuery in your VS install directory.

Marcin指出,Ms-PL下有一个2006年发布的示例(应该怎么知道?),称为DynamicQueryable。 您现在实际上已经将其存储在硬盘上。 它位于VS安装目录中的Samples \ 1033 \ CSharpSamples.zip \ LinqSamples \ DynamicQuery \ DynamicQuery下。

In fact, His Gu-ness blogged about this in January of 2008 giving this VB example:

实际上,他的Gu-ness在2008年1月写了有关此VB示例的博客

Dim Northwind As new NorthwindDataContext
Dim query = From p In Northwind.Products
Where p.CategoryID = 2 And UnitPrice > 3
Order By p.SupplierID
Select p
GridView1.DataSource = query
GridView1.DataBind()

But using the DynamicQuery library you can express the same thing like this, allowing for more dynamism. (Is that a word?)

但是使用DynamicQuery库,您可以像这样表达相同的内容,从而实现更多的动态性。 (这是一个字吗?)

Dim Northwind As new NorthwindDataContext
Dim query = Northwind.Products
.Where("CategoryID=2 And p.UnitPrice>3")
.OrderBy("SupplierID")
GridView1.DataSource = query
GridView1.DataBind()

Again, this works great when you don't know every input ahead of time. Marcin says:

同样,当您不提前知道所有输入时,此方法就很好用。 Marcin说:

DynamicQueryable is quite powerful and includes the following

DynamicQueryable功能非常强大,包括以下内容

  • Dynamic string-based querying of any LINQ provider (late-bound versions of Where, Select, OrderBy, Take, Skip, GroupBy, Any, and Count extension methods)

    基于动态字符串的任何LINQ提供程序查询( Where Select OrderBy Take Skip GroupBy AnyCount扩展方法的最新版本)

  • String-based mini expression language (like the “it” identifier in the sample below), including complex conditional statements and all operators

    基于字符串的小型表达式语言(如下面示例中的“ it”标识符),包括复杂的条件语句和所有运算符

  • Dynamic creation of classes for projections

    动态创建投影类

Now Marcin was able to rewrite my pile of Expression crap above into this luscious four line snippet. The DynamicQueryable magic is the "var result =" line.

现在,Marcin可以将我上面的表达式废话重写为这个甜美的四行代码片段。 DynamicQueryable的法宝是“ var result =“行。

protected void Page_Init(object sender, EventArgs e) {
var items = Column.Table.GetQuery();

var result = items.Select(Column.EntityTypeProperty.Name).Distinct().OrderBy("it");

foreach (var item in result) {
if (item != null) DropDownList1.Items.Add(item.ToString());
}
}

ScottGu also points to Joseph and Ben Albahari, authors of the C# 3.0 In a Nutshell book and their incredibly deep post on building type-safe predicate methods. Their PredicateBuilder is free in the LINQKit extension library and can really help out when you get even deeper into this topic.

ScottGu还指出了C#3.0简而言之书的作者Joseph和Ben Albahari,以及他们在构建类型安全谓词方法方面的深入研究。 他们的PredicateBuilder在LINQKit扩展库中是免费的,并且在您更深入地了解该主题时可以提供真正的帮助。

Oh, and seriously, stop what you're doing now and go download LINQPad, the Albahari's most wonderful gift to us all. Then, thank them, and tell them how awesome they are.

哦,很重要的是,停止您现在正在做的事情,然后下载LINQPad ,这是阿尔巴哈里给我们所有人最好的礼物。 然后,感谢他们,并告诉他们他们有多棒。

Enjoy!

请享用!

翻译自: https://www.hanselman.com/blog/the-weekly-source-code-48-dynamicqueryable-makes-custom-linq-expressions-easier

知乎周源微信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值