Linq To SQL 问题 - 不支持 SQL 转换(C# 属性问题)

发布于 2024-08-18 10:35:30 字数 1976 浏览 6 评论 0原文

我正在扩展一些 Linq to SQL 类。我有 2 个类似的语句,第一个有效,第二个无效(“不支持 SQL 转换”错误)。

var reg2 = rs.ProductRegistrations().SingleOrDefault(p => p.Product.product_name == "ACE")

var reg5 = rs.ProductRegistrations().SingleOrDefault(p => p.product_name == "ACE");

阅读此链接 LINQ: No Translation to SQL

我明白(我认为),基本上一切都需要“内联”,否则表达式树无法正确计算。第一个示例直接访问 LinqToSql EntitySet“Product”(保持所有内容内联),而第二个示例使用如下定义的属性:

public partial class ProductRegistration :IProduct
{
    public string product_name
    {
        get { return this.Product.product_name; }
    }
}

我假设我的问题是 LinqToSql 无法转换它。

我如何将“属性”变成等效的声明?我知道我需要使用 System.Linq.Expressions.Expression,但我尝试过的所有方法都不起作用(有些甚至无法编译)。也许我应该创建一个扩展方法(使用表达式),然后从属性中调用它?属性可以调用扩展方法吗?

像下面这样的事情不起作用:

public static System.Linq.Expressions.Expression<Func<IProduct, bool>> ProductName2 (string pname)
{
    return (p => p.product_name == pname);
}

底线,我知道我需要将我的访问方法包装在“表达式<....>”中但我不知道如何从属性访问它,以便上面的“reg5”变量能够正常工作。

如果有一些神奇的属性,我可以将其添加到属性中以“自动表达式”属性并使 LinqToSql 满意,而不是将其包装在 Expression<...> 中,那就太好了

很想能够做到这一点...

public partial class ProductRegistration :IProduct
{
    [Auto-Expression]
    public string product_name
    {
        get { return this.Product.product_name; }
    }
}

编辑 下面的链接和答案有效。太棒了,谢谢。我的问题的第二部分,我又得到了 2 个类似的语句,第一个有效,第二个无效(“不支持 SQL 转换”错误)。

var reg = rs.ProductRegistrations().ProductName("ACE").WithTranslations().SingleOrDefault();

var reg2 = rs.ProductRegistrations2().ProductName("ACE").WithTranslations().SingleOrDefault();

它们的区别在于,第一个返回一个具体类“IQueryable[ProductRegistration]”的 IQueryable,而第二个返回一个接口“IQueryable[我的产品]”。我想使用第二个,因为我可以跨许多不同的类使用接口,这样更通用,但它似乎不起作用。有什么想法吗?

I'm extending some Linq to SQL classes. I've got 2 similar statements, the 1st one works, the 2nd does not ("has no supported translation to SQL" error).

var reg2 = rs.ProductRegistrations().SingleOrDefault(p => p.Product.product_name == "ACE")

var reg5 = rs.ProductRegistrations().SingleOrDefault(p => p.product_name == "ACE");

After reading this link LINQ: No Translation to SQL

I understand (I think), that basically everything needs to be "inline", otherwise the expression tree can not be calculated correctly. The 1st example directly accesses the LinqToSql EntitySet "Product" (keeping everything inline), whereas the 2nd example uses a property that is defined like this:

public partial class ProductRegistration :IProduct
{
    public string product_name
    {
        get { return this.Product.product_name; }
    }
}

I'm assuming my problem is that LinqToSql cannot translate that.

How would I turn a "property" into an equivalent statement? I know I need to use the System.Linq.Expressions.Expression, but everything I've tried doesn't work (some don't even compile). Maybe I should make an Extension method (using Expression), and then call that from the property? Can a property call an extension method??

Things like below don't work:

public static System.Linq.Expressions.Expression<Func<IProduct, bool>> ProductName2 (string pname)
{
    return (p => p.product_name == pname);
}

Bottom line, I know I need to wrap my access method in an "Expression<....>" but I don't know how to access that from the property, so that the "reg5" variable above will work correctly.

Would be great if there was some magic attribute that I could just add to the property to "auto-expression" the property and make LinqToSql happy, instead of wrapping it in Expression<...>

Would love to be able to do this...

public partial class ProductRegistration :IProduct
{
    [Auto-Expression]
    public string product_name
    {
        get { return this.Product.product_name; }
    }
}

EDIT
The link and answer below works. Awesome, thanks. 2nd part of my question, again I've got 2 similar statements, the 1st one works, the 2nd does not ("has no supported translation to SQL" error).

var reg = rs.ProductRegistrations().ProductName("ACE").WithTranslations().SingleOrDefault();

var reg2 = rs.ProductRegistrations2().ProductName("ACE").WithTranslations().SingleOrDefault();

The difference in them is that the 1st one returns an IQueryable of a concrete class "IQueryable[ProductRegistration]", whereas the 2nd one returns an IQueryable of an interface "IQueryable[IProduct]". I would like to use the 2nd one, because I can slap the interface across many different classes and it's more generic that way, but it seems to not work. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃→可爱长大的 2024-08-25 10:35:30

如果有一些神奇的属性,我可以将其添加到属性中以“自动表达式”属性并使 LinqToSql 满意,而不是将其包装在 Expression<...>

有,非常接近。您仍然需要做一些工作,但 Damien Guard 和朋友已经为您完成了最困难的部分:客户端属性和任何远程 LINQ 提供程序

最酷的是,它可以与任何支持的 LINQ 提供程序一起使用您使用的表达式。

更新:第二个版本(带有接口)的问题是,Queryable 提供程序需要能够找出接口的实现者是什么,因为它需要将其音译为表姓名。但接口的全部要点是接口用户应该不知道实现类型,因此提供者将与接口进行交叉目的。所以我认为第二种形式行不通。

Would be great if there was some magic attribute that I could just add to the property to "auto-expression" the property and make LinqToSql happy, instead of wrapping it in Expression<...>

There is, very nearly. You'll still have to do some work, but Damien Guard and friends have done the hard part for you: Client-side properties and any remote LINQ provider

The cool thing is that it works with any LINQ provider which supports the Expressions you use.

Update: The problem with your second version (with the interface) is that the Queryable provider would need to be able to figure out what the implementor of the interface is, because it needs to transliterate that into a table name. But the whole point of an interface is that the interface user should be agnostic as to the implementing type, so the provider would be working at cross purposes with the interface. So I don't think the second form will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文