Справка по LINQ to DataSet Query - PullRequest
0 голосов
/ 23 июля 2011

Я действительно новичок в 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 to Dataset:

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 работать, хотя я думаю, что это будет более выгодно для меня в будущем.

Любая помощь или указатели приветствуются.

Спасибо.

Пит.

Ответы [ 2 ]

1 голос
/ 23 июля 2011

Рассмотрите возможность использования объектов POCO вместо DataSet.

Блоги @ MSDN

0 голосов
/ 23 июля 2011

Если я вас правильно понимаю, запрос 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 ;

} 

(Обратите внимание, я предполагаю, что некоторые типы полей)

Затем вы изменяете свой запрос на использование информации, т.е.

select new Info {
    Code = detail["Code"],
 ...

и наконец

    FileHelperEngine engine = new FileHelperEngine(typeof(Info)); 
    engine.WriteFile(".\\outputfile.csv", query);

и все готово.

...