LINQ to SQL:معقدة الاستعلام مع البيانات المجمعة عن تقرير من جداول متعددة على نظام الطلبات

StackOverflow https://stackoverflow.com/questions/512984

سؤال

أريد تحويل الاستعلام التالي في LINQ الجملة.أواجه الكثير من المتاعب تمكنت من الحصول على عمل.أنا فعلا حاولت بدءا من LINQ ، ولكن وجدت أن قد يكون لديك أفضل حظا إذا كتبت بطريقة أخرى.

SELECT
    pmt.guid,
    pmt.sku,
    pmt.name,
    opt.color,
    opt.size,
    SUM(opt.qty) AS qtySold,
    SUM(opt.qty * opt.itemprice) AS totalSales,
    COUNT(omt.guid) AS betweenOrders
FROM
    products_mainTable pmt 
        LEFT OUTER JOIN 
            orders_productsTable opt ON opt.products_mainTableGUID = pmt.guid
            LEFT OUTER JOIN orders_mainTable omt ON omt.guid = opt.orders_mainTableGUID AND
                (omt.flags & 1) = 1
GROUP BY
    pmt.sku, opt.color, opt.size, pmt.guid, pmt.name
ORDER BY
    pmt.sku

النتيجة النهائية هو الجدول الذي يظهر لي معلومات عن المنتج كما ترون أعلاه.كيف يمكنني كتابة هذا الاستعلام في LINQ شكل باستخدام الفهم syntax ؟

بالإضافة إلى ذلك, قد ترغب في إضافة عوامل تصفية إضافية (إلى orders_mainTable ، على سبيل المثال).

هنا هو مثال واحد حاولت أن تجعل العمل, و كانت قريبة إلى حد ما ولكن لست متأكدا إذا كان هذا هو "الصحيح" الطريقة, و لم يكن قادرا على الفريق أنه حسب الحجم و اللون من orders_productsTable.

from pmt in products_mainTable
let Purchases = 
        from opt in pmt.orders_productsTable
        where ((opt.orders_mainTable.flags & 1) == 1)
        where ((opt.orders_mainTable.date_completedon > Convert.ToDateTime("01/01/2009 00:00:00")))
        select opt
orderby pmt.sku
select new {
    pmt.guid,
    pmt.sku,
    pmt.name,
    pmt.price,  
    AvgPerOrder = Purchases.Average(p => p.qty).GetValueOrDefault(0),
    QtySold = Purchases.Sum(p => p.qty).GetValueOrDefault(),
    SoldFor = Purchases.Sum(p => p.itemprice * p.qty).GetValueOrDefault()           
}

*تحرير:

إلى أن يكون قليلا أكثر وضوحا حتى يمكنك فهم ما أحاول فعله هنا بعض مزيد من التوضيح.

يتم تخزين المنتجات في products_mainTable أوامر يتم تخزينها في orders_mainTable المنتجات التي تم طلبها يتم تخزينها في orders_productsTable

أريد إنشاء عدة تقارير على أساس المنتجات, أوامر, الخ.التنقيب في البيانات وإيجاد معنى بت العرض إلى المستخدم النهائي.

في هذه الحالة, أنا أحاول عرض المنتجات التي تم شراؤها على مدى فترة من الزمن, و هي الأكثر شعبية.كم بيعها بأي سعر و ما هو الاختراق في النظام.ربما ليس أفضل من النظام ، ولكن أنا مجرد تجارب و اختار هذا واحد.

جميع الجداول لها علاقات الجداول الأخرى.لذلك من الجدول المنتج يمكنني الحصول على أي أوامر طلب هذا المنتج ، إلخ.

أكبر مشكلة أعاني هو فهم كيف LINQ يعمل خصوصا مع تجميع البيانات المجمعة, ملحقات, الاستعلامات الفرعية ، إلخ.كان الأمر ممتعا لكنه بدءا من الحصول على محبطا لأنني أواجه صعوبة في العثور على توضيحات مفصلة حول كيفية القيام بذلك.

هل كانت مفيدة؟

المحلول 2

برونو شكرا جزيلا على المساعدة الخاصة بك!على FirstOrDefault() ربما كان أكبر مساعدة.التالية بعض ما فعلت ، و مورد آخر خطرت التالية التي يبدو للعمل بشكل جميل!هذا استعلام LINQ أدناه أعطاني ما يقرب من الدقيق النسخ المتماثل في SQL أنا نشرت أعلاه.

وهنا الموارد الأخرى وجدت على القيام LEFT JOIN في LINQ: بلوق وظيفة

الجواب النهائي:

 from pmt in products_mainTable
    join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID into tempProducts
    from orderedProducts in tempProducts.DefaultIfEmpty()
    join omt in orders_mainTable on orderedProducts.orders_mainTableGUID equals omt.guid into tempOrders
    from ordersMain in tempOrders.DefaultIfEmpty()
    group pmt by new { pmt.sku, orderedProducts.color, orderedProducts.size } into g
    orderby g.FirstOrDefault().sku
    select new {
        g.FirstOrDefault().guid,
        g.Key.sku,
        g.Key.size, 
        QTY = g.FirstOrDefault().orders_productsTable.Sum(c => c.qty),
        SUM = g.FirstOrDefault().orders_productsTable.Sum(c => c.itemprice * c.qty),
        AVG = g.FirstOrDefault().orders_productsTable.Average(c => c.itemprice * c.qty),
        Some = g.FirstOrDefault().orders_productsTable.Average(p => p.qty).GetValueOrDefault(0),
    }

نصائح أخرى

وأنا أيضا مبتدئا في LINQ. أنا لا أعرف إذا كان هذا هو الطريق الصحيح للتجمع من قبل العديد من المجالات ولكن اعتقد ان لديك لتحويل هذه المجالات تضم إلى مفتاح تمثل. لذلك، على افتراض أن جميع الحقول التجمع الخاص بك هي سلاسل أو [إينتس] يمكنك جعل مفتاح كما يلي:

        var qry = from pmt in products_mainTable
                  join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID
                  join omt in orders_mainTable on opt.orders_mainTableGUID equals omt.guid
                  where (opt.orders_mainTable.flags & 1) == 1
                  group omt by pmt.sku + opt.price + opt.size + pmt.guid + pmt.name into g
                  orderby g.sku
                  select new
                  {
                      g.FirstOrDefault().guid,
                      g.FirstOrDefault().sku,
                      g.FirstOrDefault().name,
                      g.FirstOrDefault().color,
                      g.FirstOrDefault().price,
                      AvgPerOrder = g.Average(p => p.qty).GetValueOrDefault(0),
                      QtySold = g.Sum(p => p.qty).GetValueOrDefault(),
                      SoldFor = g.Sum(p => p.itemprice * p.qty).GetValueOrDefault()
                  };

لم أكن اختبار هذا لذا يرجى معرفة ما اذا كان هذا يساعدك بأي شكل من الأشكال.

وكان هذا مفيدا جدا بالنسبة لي الشكر. كان لي كانت مشكلة مشابهة كنت أحاول لفرز من خلال فقط حالتي أبسط من ذلك بكثير وأنا لم يكن لدي أي ينضم فيها. كنت مجرد محاولة لتجميع حقل واحد، الحصول على الحد الأدنى من آخر، والفرز. (دقيقة والفرز في نفس الاستعلام)

وهنا هو SQL أردت أن إعادة في جملة ينق:

select t.Field1, min(t.Field2), COUNT(*)
from SomeTable t
group by t.Field1
order by t.Field1

وبفضل مشاركتك تمكنت في نهاية المطاف من أجل التوصل إلى هذا:

from t in SomeTable
group t by new { t.Field1 } into g
orderby g.Key.Field1
select new
{ 
  g.Key.Field1,
  code = g.Min(c => c.Field2),
  qty = g.Count()
}

ما يخلق SQL التالية وراء الكواليس:

SELECT [t1].[Field1], [t1].[value] AS [code], [t1].[value2] AS [qty]
FROM (
    SELECT MIN([t0].[Field2]) AS [value], COUNT(*) AS [value2], [t0].[Field1]
    FROM [SomeTable] AS [t0]
    GROUP BY [t0].[Field1]
    ) AS [t1]
ORDER BY [t1].[Field1]

والكمال، بالضبط ما كنت أبحث القيام به. وكان المفتاح للي أنك أظهرت أنه من الممكن القيام بذلك داخل الجديد {} وهو أمر كنت قد فكرت أبدا في محاولة. هذا هو ضخم، وأنا الآن أشعر أنني لديهم فهم أفضل بكثير في المستقبل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top