2013-08-20 31 views
1

尝试将SQL查询转换为LINQ(因为我添加了下载2个SQL表并将它们保存到内存中的DataSet的代码)。因此,我需要LINQ选择与SQL相同的东西。通过加入多个表选择多个项目

SQL查询

SELECT s.item1, s.item2, l.itemA, l.itemB 
FROM table1 s, table2 l 
WHERE l.itemA = name AND s.item1 = l.itemB 

我至今无法编译(对DBConfig是具有多个表的数据集)什么

var query = from l in DbConfig.Tables["table2"].AsEnumerable() 
      join s in DbConfig.Tables["table1"].AsEnumerable() on l.Field<string>("itemB") equals s.Field<string>("item1") 
      where l.Field<string>("itemA") == name 
      select s.item, s.item2, l.itemA, l.itemB; 

我很新的LINQ所以任何帮助会太棒了,谢谢!

+0

什么是编译器错误? –

回答

3

首先,请注意,当您拨打AsEnumerable时,必须在客户端而不是SQL服务器上执行查询。我会强烈建议离开表格为IQueryable的以避免这种情况。

接下来,作为Tim S. explains,由于您的表格不是强类型,请使用Field<T>方法检索列值。

最后,如果你想返回多列,则需要组的结果为匿名类型:

var query = from l in DbConfig.Tables["table2"] 
      join s in DbConfig.Tables["table1"] 
      on l.Field<string>("itemB") equals s.Field<string>("item1") 
      where l.Field<string>("itemA") == name 
      select new { 
       item = s.Field<string>("item"), 
       item2 = s.Field<string>("item2"), 
       itemA = l.Field<string>("itemA"), 
       itemB = l.Field<string>("itemB") 
      }; 

或者创建一个名为类型来表示结果:

public class MyResultType { 
    public string item { get; set; } 
    public string item2 { get; set; } 
    public string itemA { get; set; } 
    public string itemB { get; set; } 
} 

var query = from l in DbConfig.Tables["table2"] 
      join s in DbConfig.Tables["table1"] 
      on l.Field<string>("itemB") equals s.Field<string>("item1") 
      where l.Field<string>("itemA") == name 
      select new MyResultType { 
       item = s.Field<string>("item"), 
       item2 = s.Field<string>("item2"), 
       itemA = l.Field<string>("itemA"), 
       itemB = l.Field<string>("itemB") 
      }; 
+0

谢谢!我试过这个,它说“DataRow不包含'itemx'的定义,等等。当我尝试这样选择:'select new {servers.Field (“servername”),servers.Field (“ip”)};'它说“一个匿名类型不能有多个同名的属性”。有什么想法吗? – Hershizer33

+1

@ Hershizer33在这种情况下,您必须指定名称:'select new {servername = servers.Field (“servername”),ip = servers.Field (“ip”)};' - see [* *匿名类型(C#编程指南)**](http://msdn.microsoft.com/en-us/library/vstudio/bb397696.aspx)。 –

+0

似乎正在工作......最后一个问题,我怎样才能将'query'变成一个DataTable?似乎我可以做它购买创建一个DataTable,添加列,并通过'query'进行传递,但我觉得必须有更好的方法... – Hershizer33

2

由于您没有处理强类型结果,因此无法选择结果,例如s.item1;您必须使用Field<>(或类似的东西),就像查询的其余部分一样。另外,既然你只能在LINQ查询中选择一个对象,并且你想要四个值,你应该选择一个新的匿名类型,或者创建一个类型来存储它们。

var query = from l in DbConfig.Tables["table2"].AsEnumerable() 
      join s in DbConfig.Tables["table1"].AsEnumerable() 
       on l.Field<string>("itemB") equals s.Field<string>("item1") 
      where l.Field<string>("itemA") == name 
      select 
     new { Item1 = s.Field<string>("item1"), Item2 = s.Field<string>("item2"), 
      ItemA = l.Field<string>("itemA"), ItemB = l.Field<string>("itemB") }; 
1

请试试这个

var data=from dr1 in DbConfig.Tables["table2"].AsEnumerable() 
     join dr2 in DbConfig.Tables["table1"].AsEnumerable() 
     on dr1.Field<string>("itemB") equals dr2.Field<string>("item1") 
     where dr1.Field<string>("itemA") == name 
     select new {item = dr2.Field<string>("item"), 
       item2 = dr2.Field<string>("item2"), 
       itemA = dr1.Field<string>("itemA"), 
       itemB = dr1.Field<string>("itemB") } 

总是使用命名的类型(自定义类),而不是匿名类型的可维护性和可扩展性。

+0

@ p.s.w.g是的,你是对的。我的查询不正确我错过了其他连接条件。我会更新我的回答 – kbvishnu

+0

感谢您的纠正。 –

0

如果你想看到的lambda语法

var query = DbConfig.Tables["table1"].AsEnumerable() 
      .Join 
      (
       DbConfig.Tables["table2"].AsEnumerable(), 
       x=>x.Field<string>("item1"), 
       x=>x.Field<string>("itemB"), 
       (t1,t2)=>new {t1,t2} 
      ) 
      .Where 
      (
       x=>x.t2.Field<string>("itemA") == name 
      ) 
      .Select 
      (
       x=> 
       new 
       { 
        x.t1.Field<string>("item"), 
        x.t1.Field<string>("item2"), 
        x.t2.Field<string>("itemA"), 
        x.t2.Field<string>("itemB") 
       } 
      )