LINQ to DataSet 查询帮助
Posted
技术标签:
【中文标题】LINQ to DataSet 查询帮助【英文标题】:LINQ to DataSet Query Help 【发布时间】:2011-10-11 12:52:59 【问题描述】:我对 LINQ 真的很陌生,所以我希望有人可以帮助我。我有一个数据库,我需要从中运行一个大型查询,但它是一个非常旧的 ODBC 驱动程序,需要很长时间才能响应(即使是一个简单的查询也需要 30 分钟以上)。将所有数据转储到数据集中只需要大约 2-3 分钟,所以我认为这是最好的,然后我可以运行 LINQ to Dataset 查询。我似乎无法让查询工作,我有点困惑。我将所有数据放入 SQL Express 数据库以测试 LINQ to SQL 查询,以确保我走的是正确的道路。我没有这个选项,应用程序将在哪里运行,因为环境总是不同的。
SQL:
SELECT Invoice_detail.Code, Invoice_detail.Description, Product_master.Comment AS Packing, Invoice_detail.QtyInv AS INV, Invoice_detail.QtyBackOrder AS BO, Alternate_product_codes.MasterBarCode AS BarCode, Invoice_detail.PriceAmt AS Price, Invoice_detail.DiscPerc AS Disc, ROUND(Invoice_detail.TaxableAmt/Invoice_detail.QtyInv,2) AS Nett FROM ((Invoice_detail INNER JOIN Product_master ON Invoice_detail.Code = Product_master.Code) INNER JOIN Invoice_header ON Invoice_detail.InternalDocNum = Invoice_header.InternalDocNum AND Invoice_detail.DocType = Invoice_header.DocType) LEFT JOIN Alternate_product_codes ON Invoice_detail.Code = Alternate_product_codes.Code WHERE Invoice_header.DocNum = '0' AND Invoice_header.DocType = 1 AND Invoice_detail.LineType = 1 AND Invoice_detail.QtyInv > 0
LINQ to SQL:
from detail in INVOICE_DETAILs
join prodmast in PRODUCT_MASTERs on detail.Code equals prodmast.Code
join header in INVOICE_HEADERs on new detail.InternalDocNum, detail.DocType equals new header.InternalDocNum, header.DocType
join prodcodes in ALTERNATE_PRODUCT_CODES on detail.Code equals prodcodes.Code into alt_invd
from prodcodes in alt_invd.DefaultIfEmpty()
where
header.DocType == 1 &&
detail.LineType == 1 &&
detail.QtyInv > 0 &&
header.Date > DateTime.Parse("17/07/2011").Date &&
header.DocNum.Trim() == "119674"
select new
detail.Code,
detail.Description,
Packing = prodmast.Comment,
INV = detail.QtyInv,
BO = detail.QtyBackOrder,
Barcode = prodcodes.MasterBarCode,
Price = detail.PriceAmt,
Disc = detail.DiscPerc,
Nett = Math.Round(Convert.ToDecimal(detail.TaxableAmt/detail.QtyInv),2,MidpointRounding.AwayFromZero)
LINQ 到数据集:
var query = from detail in ds.Tables["Invoice_detail"].AsEnumerable()
join prodmast in ds.Tables["Product_master"].AsEnumerable() on detail["Code"] equals prodmast["Code"]
join header in ds.Tables["Invoice_header"].AsEnumerable() on new docnum = detail["InternalDocNum"], doctype = detail["DocType"] equals new docnum = header["InternalDocNum"], doctype = header["DocType"]
join prodcodes in ds.Tables["Alternate_product_codes"].AsEnumerable() on detail["Code"] equals prodcodes["Code"] into alt_invd
from prodcodes in alt_invd.DefaultIfEmpty()
where
(int)header["DocType"] == 1 &&
(int)detail["LineType"] == 1 &&
(int)detail["QtyInv"] > 0 &&
//header.Field<DateTime>("Date") > DateTime.Parse("17/07/2011").Date &&
header.Field<DateTime>("Date") > DateTime.Now.Date.AddDays(-7) &&
header.Field<string>("DocNum").Trim() == "119674"
select new
Code = detail["Code"],
Description = detail["Description"],
Packing = prodmast["Comment"],
INV = detail["QtyInv"],
BO = detail["QtyBackOrder"],
Barcode = prodcodes["MasterBarCode"],
Price = detail["PriceAmt"],
Disc = detail["DiscPerc"],
Nett = Math.Round(Convert.ToDecimal((double)detail["TaxableAmt"] / (int)detail["QtyInv"]), 2, MidpointRounding.AwayFromZero)
;
我需要运行 LINQ to DataSet 查询,然后将结果放入 DataTable 中,以便导出为 CSV。该查询将返回许多行,因此我可以看到 CopyToDataTable 方法,但是除非它是类型化的数据集,否则它似乎不起作用。我正在使用 ODBC 数据适配器填充方法,因此没有专门设置我正在填充的数据表上的数据类型。原因是这些表中有很多列,将它们全部设置好会很耗时。
LINQ 是最佳选择吗?我接近了吗?我是否必须为所有列和数据类型设置数据表?我能想到的唯一另一种方法是每次都将数据转储到访问数据库中并从那里查询。不过,我对让 LINQ 工作感到更加好奇,因为我认为这对我未来的发展会更有益。
感谢任何帮助或指点。
谢谢。
皮特。
【问题讨论】:
【参考方案1】:考虑使用 POCO 对象而不是 DataSet。
Blogs @ MSDN
【讨论】:
【参考方案2】:如果我对您的理解正确,Linq To Dataset 查询检索到正确的信息,但您无法将信息导出到 csv。
如果这只是您需要使用示例中的九个字段创建的一个 csv 文件,您可以使用 csv 库(例如 FileHelpers)来导出信息。
为了给你一个涉及额外工作的例子,你需要定义一个类,例如
[DelimitedRecord(",")]
public class Info
[FieldQuoted()]
public string Code ;
[FieldQuoted()]
public string Description ;
[FieldQuoted()]
public string Packing ;
public decimal INV ;
public decimal BO ;
[FieldQuoted()]
public string Barcode ;
public decimal Price ;
public decimal Disc ;
public decimal Nett ;
(注意,我猜是一些字段类型)
然后您将查询更改为使用 Info ,即
select new Info
Code = detail["Code"],
...
最后
FileHelperEngine engine = new FileHelperEngine(typeof(Info));
engine.WriteFile(".\\outputfile.csv", query);
你就完成了。
【讨论】:
以上是关于LINQ to DataSet 查询帮助的主要内容,如果未能解决你的问题,请参考以下文章
如何在 LINQ to DataSet 的匿名类中使用基于查询数据的条件?