使用linq-to-sql从多个表中检索数据

时间:2014-10-21 13:23:17

标签: c# winforms linq-to-sql

我们需要使用Linq-to-SQL在表单上填充一堆控件来检索数据。为了获取数据,我们需要连接几个表。

我们有以下方法:

第一档:

public IEnumerable<object> getPRs()
{
    DataContext db = new DataContext();

    var prQuery = (from p in db.Invoice
                   join prd in db.InvoiceDetails on p.ID equals prd.ID
                   join pra in Accounting on p.ID equals pra.ID
                   where 1 == 1
                   orderby p.DownloadDate descending, p.PRNumber, Convert.ToInt32(p.Item)
                   select new
                          {
                              p.ID,
                              DownloadDate = Convert.ToString(p.DownloadDate),
                              p.PRNumber,
                              p.Item,
                              p.Material,
                              p.ClientMaterial,
                              p.Description,
                              p.Client,
                              p.Price,
                              p.UC,
                              prd.Supplier,
                              prd.Duns,
                              prd.RFQ,
                              prd.RFQDate,
                              prd.PO,
                              prd.PODate,
                              POValue = prd.Price * prd.Quantity,
                              pra.SO,
                              pra.SODate,
                              pra.SOValue,
                              pra.GR,
                              pra.GRDate,
                              pra.GI,
                              pra.GIDate,
                              pra.SInvoice,
                              pra.SInvoiceDate,
                              pra.CInvoice,
                              pra.CInvoiceDate,
                              p.isActive
                          }).ToList();
    return prQuery;
}

我们在第二个文件中调用这样的方法:

IEnumerable<object> data = FirstFile.GetPRs();
PRNumberTextBox.Text = data.PRNumber;

最后一行会出错,因为我们无法从数据对象访问PRNumber成员。为了填写所有文本框,我们如何调用我们的函数并添加必要的信息?

2 个答案:

答案 0 :(得分:2)

您将返回匿名类型。我建议你创建一个模型类来返回你的数据:

public class PRModel
{
    public int ID { get; set; }
    public string DownloadDate { get; set; }
    //etc... you can fill in the rest yourself
}

然后你的查询变成这样:

var prQuery = (from p in db.Invoice
               join prd in db.InvoiceDetails on p.ID equals prd.ID
               join pra in Accounting on p.ID equals pra.ID
               where 1 == 1
               orderby p.DownloadDate descending, p.PRNumber, Convert.ToInt32(p.Item)
               select new PRModel //<---This is the change here
               {
                   ID = p.ID,
                   DownloadDate = Convert.ToString(p.DownloadDate),
                   PRNumber = p.PRNumber,
                   //snipp
               }

最后,您的返回类型现在应为IEnumerable<PRModel>。此外,因为它是一个枚举(即你可能有0,1或多个项目),你需要迭代它们:

IEnumerable<PRModel> data = FirstFile.GetPRs();
foreach(var pr in data)
{
    PRNumberTextBox.Text = pr.PRNumber;
}

修改

在这种情况下,如果您只想返回单独的发票,则更容易做到。而不是这样做:

select new PRModel
{
    //lots of rows
}

你可以这样做:

select p

这又会使您的返回类型为IEnumerable<Invoice>

答案 1 :(得分:1)

问题
PRNumber不是IEnumerable<object>的成员。您需要遍历IEnumerable才能访问每个元素。

<强>解决方案:
第二个问题是您隐式将 linq查询中的anonymous types投射到object,因此您从getPRS()获取的列表中的每个元素都将是对象。如果不转换为特定类型(根据@DavidG解决方案 - 每个聚合函数的新类/类型)或使用dynamic在运行时定义类型,则无法访问属性。 最简单的解决方法是将返回类型更改为IEnumerable<dynamic>

public IEnumerable<dynamic> GetList()
        {
            var list = new List<int> {1, 2, 3, 4};
            return (from i in list
                   select new {
                       Integer = i,
                       Str = "Str" + i
                   }).ToList();
        }

然后:

var items = GetList();
Console.WriteLine(items.First().Integer); // prints "1" to console