Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可转换为SQL的Linq到SQL表达式属性_C#_Linq_Linq To Sql - Fatal编程技术网

C# 可转换为SQL的Linq到SQL表达式属性

C# 可转换为SQL的Linq到SQL表达式属性,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,我有一个LINQ-to-SQL类,我们称之为Test,我希望能够使用LINQ查询访问属性,但我遇到了著名的“不支持转换为SQL”运行时错误。我对概念问题感兴趣。这是我的简化课程: public class Test { public int ID {get; set;} // Stored in Database public int NonForeignKeyValue {get; set;} // Stored in Database } 下面是我试图实现的一个示例,但我不希望总

我有一个LINQ-to-SQL类,我们称之为
Test
,我希望能够使用LINQ查询访问属性,但我遇到了著名的“不支持转换为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)
最终,这就是我希望我的代码看起来的样子,但它会出错。我基本上希望返回包含一些数据库计算值的所有条目:

using (DataContext db =  new DataContext())
{
   var q = db.GetTable<Test>()
             .Where(x => x.IsInOtherTable && x.OtherStuff); //Error
}       
使用(DataContext db=newdatacontext())
{
var q=db.GetTable()
.Where(x=>x.IsInOtherTable&&x.OtherStuff);//错误
}       
基本上,每次我想检查测试是否在另一个表中有某些信息时,我都试图避免编写这些代码。我对我描述的问题不太感兴趣,我更感兴趣的是如何在概念上将连接部分添加到SQL中,并且仍然使用LINQ。我猜我用的是Linq.Expression,但我真的不知道,也不知道该怎么做

顺便说一句,我可以编写实际的SQL,因为它没有那么复杂,但我想知道如何绕过这个问题,并且仍然使用LINQ

编辑:我尝试了这个属性,但得到了相同的错误。更复杂的是,只需将返回类型更改为表达式

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));
       }
    }
}        
public System.Linq.Expressions.Expression存在
{
得到
{
使用(DataContext db=newdatacontext())
{
返回i=>db.GetTable()
.Any(x=>x.NonForeignKeyValue==i.NonForeignKeyValue));
}
}
}        

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

在您的示例中,您传递的不是表达式,而是-属性、委托,即表达式访问者无法“介入”的内容

总的来说,试着重新考虑你的条件,这样你就没有了
bool
,而是有了
Expression
等等


首先,我认为您可能高估了“总是显式地在LINQ中编写连接的开销”。这是一个额外的代码行,它的优点是可以相对地自我记录您正在做的事情(总是一件好事),任何其他方法都将首先转换为SQL,然后转换为一个查询计划,该计划的执行成本至少与SQL相同,可能更高(SQLServer是一个很好的连接!)

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

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

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

然后在DataContext派生类上定义一个受保护的方法,该方法与C#术语中的签名相匹配,并将其映射到该SQL函数。(由于这不是可以在C#version中提供合理的非db使用版本的,因此可以通过调用来实现C#函数)

然后可以使用该方法而不是join


尽管如此,这在代码中可能不太容易解释,并且有可能比仅保留联接效率更低。

对于初学者,所有要一起使用的查询都必须使用相同的数据上下文是否嵌套使用(…)块折叠为一个使用(…)块?这是如何工作的?你的链接有一些关于表达式的信息,但它不能解决你想再次到数据库获取更多信息的情况…谢谢。我要试着走整条路。我的目标是尽可能地抽象出复杂性,因为我使用的是高度规范化的模式。我基本上是在尝试实现功能,然后如果(更像是什么时候)出现性能问题,我可以解决它们。这可能会落入需要在以后解决的问题中。
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));
       }
    }
}