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
Vb.net Linq到实体:带WHERE子句的左外连接、计算和投影_Vb.net_Linq_Linq To Entities - Fatal编程技术网

Vb.net Linq到实体:带WHERE子句的左外连接、计算和投影

Vb.net Linq到实体:带WHERE子句的左外连接、计算和投影,vb.net,linq,linq-to-entities,Vb.net,Linq,Linq To Entities,我很难弄清楚如何将多个列上的简单SQL左外部联接和where子句转换为工作的Linq to Entities查询。只有两张桌子。我需要表1中所有行的值,而不管表2中是否匹配,但是连接多个列是很困难的。我还需要在查询中做一个简单的计算,但也找不到。SQL中的查询如下所示: select t1.tableid1, t1.tableid2, t1.fieldvalue1, t2.fieldvalue2, isnull(t2.fieldvalue2,0) / t1.fieldvalue1 as calc

我很难弄清楚如何将多个列上的简单SQL左外部联接和where子句转换为工作的Linq to Entities查询。只有两张桌子。我需要表1中所有行的值,而不管表2中是否匹配,但是连接多个列是很困难的。我还需要在查询中做一个简单的计算,但也找不到。SQL中的查询如下所示:

select t1.tableid1,
t1.tableid2,
t1.fieldvalue1,
t2.fieldvalue2,
isnull(t2.fieldvalue2,0) / t1.fieldvalue1 as calcvalue
t1.fieldvalue1 - isnull(t2.fieldvalue2,0) as calcvalue2
from table1 t1
left outer join table2 t2 
    on t1.tableid1 = t2.tableid1
    and t1.tableid2 = t2.tableid2
    and t1.tableid3 = t2.tableid3
where t1.tableid1 = @somevalue
On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
我可以做单列左连接,但我似乎找不到多个列的正确语法,更不用说不知道如何添加或减去列上的值。下面是我的最佳猜测,但我得到一个类型预期错误(在“new”之后和第一个左括号之前):

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
最佳猜测:

Dim query = From t1 In dtTable1 _
                         Group Join t2 In dtTable2 _
                         On New (t2.Field(Of String)("tableid1"), t2.Field(Of String)("tableid2")) Equals _
                            (t1.Field(Of String)("tableid1"), t1.Field(Of String)("tableid2")) _
                         Into t2outer = Group _
                         From t2 In t2outer.DefaultIfEmpty() _
                         Select New With _
                        { _
                            .t1_tableid1 = t1.Field(Of String)("tableid1"), _
                            .t1_tableid2 = t1.Field(Of String)("tableid2"), _
                            .t1_fieldvalue1 = t1.Field(Of Integer)("fieldvalue1"))
                            .t2_fieldvalue2 = If(t2 Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2"))
                        }
On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _

@格特,这让我离得够近了。我认为格式有点不正确,因为我必须添加大括号而不是括号,并且在“Key”关键字和id之间放置了一个空格:

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
多亏了Gert,我才能够像SQL查询中描述的那样工作。有关SQL查询的完整工作表示形式,请参见以下内容:

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
Dim query = From t1 In dtTable1 _
    Where (T1.Field(Of String)("fieldvalue1") = SOMEVALUE) _
     Group Join t2 In dtTable2 _
     On New (t2.Field(Of String)("tableid1"), t2.Field(Of String)("tableid2")) Equals _
        (t1.Field(Of String)("tableid1"), t1.Field(Of String)("tableid2")) _
     Into t2outer = Group _
     From t2 In t2outer.DefaultIfEmpty() _
     Select New With _
    { _
        .t1_tableid1 = t1.Field(Of String)("tableid1"), _
        .t1_tableid2 = t1.Field(Of String)("tableid2"), _
        .t1_fieldvalue1 = t1.Field(Of Integer)("fieldvalue1"))
        .t2_fieldvalue2 = If(t2 Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2"))
        .calcvalue = If(t2.Field(Of Integer)("fieldvalue2") Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2")) _
            / CType(t1.Field(Of String)("fieldvalue1"), Integer), 
        .calcvalue2 = CType(t1.Field(Of String)("fieldvalue1"), Integer) _
            - If(t2.Field(Of Integer)("fieldvalue2") Is Nothing, CType("0", Integer), t2.Field(Of Integer)("fieldvalue2")) _
    }

对于实体,您有一个容器,并根据它们的名称评估表。此where子句按字段值筛选结果,并可与更多值连接。{}中的部分供您更改以匹配您的实体。这个查询是一个
IEnumerable(属于{your entity})
-非常适合数据绑定

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
Dim query = model.{table name}.Where(Function(o) o.{column name} = {some value}).ToList()

首先,如果您在多个字段上分组,您将比较匿名类型,因此

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
On
   New (t2.Field(Of String)("tableid1"), t2.Field(Of String)("tableid2"))
Equals
       (t1.Field(Of String)("tableid1"), t1.Field(Of String)("tableid2"))
应更改为用于创建匿名类型的语法(与您稍后在查询中使用的相同):

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
但是

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
在C#中,这就足够了,因为对于匿名类型,C#编译器使用基于值的相等。然而,由于某些原因,与VB不同的是,它使用引用相等。因此
Equals
总是
false
,因为第一个对象与第二个对象不是同一个对象

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
幸运的是,VB有
关键字,允许您在比较匿名对象时指示要使用的属性。最后的语法是:

On New With {
                        Key .id1 = t2.Field(Of String)("tableid1"), _
                        Key .id2 = t2.Field(Of String)("tableid2")
                        } _
                    Equals _
                    New With {
                        Key .id1 = t1.Field(Of String)("tableid1"), _
                        Key .id2 = t1.Field(Of String)("tableid2")
                        } _
On
  New With {Key .id1 = t2.Field(Of String)("tableid1"),
            Key. id2 = t2.Field(Of String)("tableid2")}
Equals
  New With {Key .id1 = t1.Field(Of String)("tableid1"),
            Key .id2 = t1.Field(Of String)("tableid2")}

那我就糊涂了。。。如果外部联接是一个列,我实际上可以让它工作,但是一旦我添加了多个列,它就会出错。你能用我的例子详细说明一下吗?在阅读了几个c#linq查询之后,我想尝试一下:“On New(t2.Field(of String)(“tableid1”),t2.Field(of String)(“tableid2”)等于”位。我希望语法可能有点类似。如果在制作模型之前在DB中建立关系,您将拥有
导航属性
。在这里,您可以通过
表名
字段
访问相关表。示例:如果表
Customer
Orders
相关,则会有一个类似于:
Customers.Orders.OrderId
的属性,并且可以在上面的查询筛选器中使用该属性。这让我非常接近。我觉得格式有点不对劲,非常感谢,这让我足够接近了(见我修改后的原始帖子)。我相信vb.net的格式可能有点不合适?现在我应该在哪里添加where子句,因为我需要它来过滤表1和表2(如果它存在的话)。甚至可以在链接查询中进行简单的计算吗?i、 e.t1.FieldValue1-t2.FieldValue2=CalculatedValue1通常用于嵌套的
Where
s最方便的方法是将查询语法与流畅的(方法)语法混合使用:
dtTable1.Where(…)
组连接dtTable2中的t2.Where(…)
。当然,您可以将计算出的属性放入投影(
Select
),但它们应该看起来像
。t1\u fieldvalue1=t1.Field(…)-t1.Field(…)
。工作非常出色。非常感谢。我在原来的帖子中添加了完整的代码,以帮助将来的任何人。再次感谢你,格特!