我有一个LINQ to SQL类,我们称之为Test ,我希望能够使用LINQ查询访问属性,但我得到了着名的“No Supported Translation to SQL”运行时错误。 我对概念问题很感兴趣。 这是我的简化课程:

public class Test
{ 
  public int ID {get; set;} // Stored in Database
  public int NonForeignKeyValue {get; set;} // Stored in Database
}

这是我正在尝试完成的一个示例,但我不希望总是在LINQ中显式写入连接的开销:

var db = (new DataContext()).GetTable<Test>();
var q = (from t in db.GetTable<Test>()
         join o in db.GetTable<OtherTable>() on o.ID equals t.ID
         where t.OtherStuff
         select t)

我希望能够向Test添加一个属性,告诉我OtherTable中是否有可以与Test连接的行:

  public bool IsInOtherTable
  {
    get
    {
       return (new DataContext())
              .GetTable<OtherTabke>()
              .Any(x => x.NonForeignKeyValue == this.NonForeignKeyValue));
    }
  }

最终这就是我希望我的代码看起来像,但它错误。 我基本上想要返回包含一些数据库计算值的所有条目:

using (DataContext db =  new DataContext())
{
   var q = db.GetTable<Test>()
             .Where(x => x.IsInOtherTable && x.OtherStuff); //Error
}       

我基本上试图保存自己,每次我想检查Test是否在另一个表中有某些信息时编写此代码。 我对我描述的确切问题不感兴趣,我对如何在概念上将连接部分添加到SQL并仍使用LINQ更感兴趣。 我猜我使用Linq.Expression,但我真的不知道,我不知道该怎么做。

顺便说一句,我可以编写实际的SQL,因为它并不复杂,但我想知道如何解决这个问题仍然使用LINQ。

编辑:我尝试了这个属性,但我得到了同样的错误。 将返回类型更改为Expression更复杂

public System.Linq.Expressions.Expression<Func<Article3, bool>> Exists
{
    get
    {
       using (DataContext db =  new DataContext())
       {
         return i => db.GetTable<OtherTable>()
                       .Any(x => x.NonForeignKeyValue == i.NonForeignKeyValue));
       }
    }
}        

===============>>#1 票数:1

每次linq生成器将代码转换为查询时,它都必须处理表达式树。

在你的例子中,你不是传递表达式而是 - 属性,委托,即表达式访问者无法“进入”的东西。

在一般情况下,尝试重新考虑你的条件,使代替bool你有Expression<T, bool>等。

http://netpl.blogspot.com/2008/02/linq-to-object-vs-linq-to-sql-and.html

===============>>#2 票数:0 已采纳

首先,我认为你可能会高估“始终在LINQ中明确编写连接的开销”。 这是一个额外的代码行,它具有相对自我记录的优势,就像你正在做的事情一样(总是一件好事),而任何其他方法都将首先转变为SQL,然后转变为一个查询计划。至少执行成本高,可能更昂贵(SQLServer是一个很好的连接!)

尽管如此,我还能想到两种选择。

一种是在类上有一个EntityRef属性,用于定义与另一个表的这种关系。 然后,您可以测试查询中是否为null(如果它位于一对多关系的另一侧,则为EntitySet )。

另一种是定义一个SQL函数,该函数返回一个bit结果,指示id是否引用与另一个表相关或不相关的行。

然后在DataContext派生类上定义一个与C#术语中的签名匹配的受保护方法,并将Function属性映射到该SQL函数。 (因为这不是你可以在C#版本中提供合理的非db-using版本的东西,你可以通过调用ExecuteMethodCall来实现C#函数)。

然后,您可以使用该方法而不是连接。

尽管如此,这在代码中可能不太明显,并且存在效率低于仅仅保持连接的风险。

  ask by Mark translate from so

未解决问题?本站智能推荐: