LINQ-to-SQL:转换 Func到表达式>
LINQ-to-SQL 对我来说是一个 PITA。我们使用它与数据库进行通信,然后通过 WCF 将实体发送到 Silverlight 应用程序。一切都工作正常,直到开始编辑 (CUD) 实体及其相关数据。
我终于能够设计出两个允许 CUD 的 for 循环。我尝试重构它们,而且非常接近,直到我发现我不能总是用 L2S 来做 Lambda。
public static void CudOperation<T>(this DataContext ctx, IEnumerable<T> oldCollection, IEnumerable<T> newCollection, Func<T, T, bool> predicate)
where T : class
{
foreach (var old in oldCollection)
{
if (!newCollection.Any(o => predicate(old, o)))
{
ctx.GetTable<T>().DeleteAllOnSubmit(ctx.GetTable<T>().Where(o => predicate(old, o)));
}
}
foreach (var newItem in newCollection)
{
var existingItem = oldCollection.SingleOrDefault(o => predicate(o, newItem));
if (existingItem != null)
{
ctx.GetTable<T>().Attach(newItem, existingItem);
}
else
{
ctx.GetTable<T>().InsertOnSubmit(newItem);
}
}
}
调用者:
ctx.CudOperation<MyEntity>(myVar.MyEntities, newHeader.MyEntities,
(x, y) => x.PkID == y.PkID && x.Fk1ID == y.Fk1ID && x.Fk2ID == y.FK2ID);
这几乎成功了。但是,我的 Func 需要是一个 Expression>,这就是我陷入困境的地方。
有谁可以告诉我这是否可能?由于 SharePoint 2010,我们必须使用 .NET 3.5。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只需将参数从: 更改
为:
表达式由编译器生成。
现在的问题是如何使用它。
在您的情况下,您需要一个
Func
和 一个Expression
,因为您在Enumerable
LINQ 中使用它查询(基于函数)以及 SQL LINQ 查询(基于表达式)。在:
old
参数已修复。因此,我们可以将参数更改为:这意味着我们可以提供一个参数(“固定”参数)并返回一个表达式。
我们还需要在
Any
中使用它。要从表达式中获取 Func,我们可以调用 Compile():您可以对下一部分执行相同的操作。
有两个问题:
Compile()
批次可能会影响性能。我不确定它实际上会产生多大的影响,但我会对其进行分析以进行检查。(x,y) => ...
你将传递x =>; y => ...
。我不确定这对你来说是否是件大事。可能有更好的方法来做到这一点:)
这是一个替代方法,它应该更快一点,因为表达式只需编译一次。创建一个将“应用”一个参数的重写器,如下所示:
然后像这样使用它:
Just change the parameter from:
To:
The Expression is generated by the compiler.
Now, the issue is how to use this.
In your case, you need both a
Func
and anExpression
, since you're using it inEnumerable
LINQ queries (func based) as well as the SQL LINQ queries (expression based).In:
The
old
parameter is fixed. So we could change the parameter to:This means we can supply one argument (the 'fixed' one) and get back an expression.
We also need to use this in
Any
. To get a Func from an Expression we can callCompile()
:You can do the same thing with the next part.
There are two issues:
Compile()
lots. I'm not sure how much effect it would actually have, but I'd profile it to check.(x,y) => ...
you will be passingx => y => ...
. I'm not sure if this is a big deal for you.There might be a better way to do this :)
Here's an alternate method, which should be a bit faster, since the Expression only has to be compiled once. Create a rewriter that will 'apply' one argument, like this:
Then use it like this: