c# - الفرق بين حدد و SelectMany




linq-to-sql linq (8)

أنا أفهم SelectMany للعمل مثل اختصار الانضمام.

حتى تتمكن من:

var orders = customers
             .Where(c => c.CustomerName == "Acme")
             .SelectMany(c => c.Orders);

لقد كنت أبحث في الفرق بين Select و SelectMany ولكني لم أتمكن من العثور على إجابة مناسبة. أنا بحاجة لمعرفة الفرق عند استخدام LINQ إلى SQL ولكن كل ما وجدته هو أمثلة صفيف قياسية.

يمكن للشخص تقديم مثال على LINQ إلى SQL؟


إنها أفضل طريقة لفهم أعتقد.

            var query =
            Enumerable
                .Range(1, 10)
                .SelectMany(ints => Enumerable.Range(1, 10), (a, b) => $"{a} * {b} = {a * b}")
                .ToArray();

        Console.WriteLine(string.Join(Environment.NewLine, query));

        Console.Read();

مثال جدول الضرب.


حدد إسقاطًا بسيطًا من رأس واحد إلى عنصر النتيجة. Select- يتم استخدام العديد عند وجود عدة عبارات من عبارات في تعبير استعلام: يتم استخدام كل عنصر في التسلسل الأصلي لإنشاء تسلسل جديد.


دون الحصول على التقنية للغاية - قاعدة بيانات مع العديد من المنظمات ، كل مع العديد من المستخدمين: -

var orgId = "123456789";

var userList1 = db.Organizations
                   .Where(a => a.OrganizationId == orgId)
                   .SelectMany(a => a.Users)
                   .ToList();

var userList2 = db.Users
                   .Where(a => a.OrganizationId == orgId)
                   .ToList();

كلاهما إرجاع نفس قائمة ApplicationUser للمؤسسة المحددة.

أول "مشاريع" من منظمة إلى مستخدمين ، والاستعلامات الثانية جدول المستخدمين مباشرة.


قد لا تكون بعض SelectMany ضرورية. أقل من 2 الاستعلامات تعطي نفس النتيجة.

Customers.Where(c=>c.Name=="Tom").SelectMany(c=>c.Orders)

Orders.Where(o=>o.Customer.Name=="Tom")

بالنسبة لعلاقة رأس بأطراف ،

  1. إذا كان البدء من "1" ، هناك حاجة إلى SelectMany ، فإنه يسوي الكثير.
  2. إذا كان البدء من "العديد" ، ليست هناك حاجة SelectMany. ( لا يزال من الممكن التصفية من "1" ، وهذا أيضًا أبسط من طلب الانضمام القياسي القياسي)
from o in Orders
join c in Customers on o.CustomerID equals c.ID
where c.Name == "Tom"
select o

هناك العديد من الأحمال الزائدة على SelectMany . واحد منهم يسمح لك للحفاظ على تتبع أي علاقة بين الوالدين والأطفال أثناء عبور التسلسل الهرمي.

مثال : لنفترض أن لديك البنية التالية: League -> Teams -> Player

يمكنك بسهولة إرجاع مجموعة مسطحة من اللاعبين. ومع ذلك قد تفقد أي إشارة إلى الفريق الذي يعتبر اللاعب جزءًا منه.

لحسن الحظ ، هناك حمل زائد لهذا الغرض:

var teamsAndTheirLeagues = 
         from helper in leagues.SelectMany
               ( l => l.Teams
                 , ( league, team ) => new { league, team } )
                      where helper.team.Players.Count > 2 
                           && helper.league.Teams.Count < 10
                           select new 
                                  { LeagueID = helper.league.ID
                                    , Team = helper.team 
                                   };

تم أخذ المثال السابق من مدونة Dan IK:

http://blogs.interknowlogy.com/2008/10/10/use-linqs-selectmany-method-to-flatten-collections/

أوصي بشدة بإلقاء نظرة على ذلك.


SelectMany() إمكانية طي تسلسل متعدد الأبعاد بطريقة تتطلب خلافًا آخر Select() أو تكرارًا.

مزيد من التفاصيل في هذا بلوق وظيفة .


SelectMany بتسوية الاستعلامات التي تعرض قوائم القوائم. فمثلا

public class PhoneNumber
{
    public string Number { get; set; }
}

public class Person
{
    public IEnumerable<PhoneNumber> PhoneNumbers { get; set; }
    public string Name { get; set; }
}

IEnumerable<Person> people = new List<Person>();

// Select gets a list of lists of phone numbers
IEnumerable<IEnumerable<PhoneNumber>> phoneLists = people.Select(p => p.PhoneNumbers);

// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);

// And to include data from the parent in the result: 
// pass an expression to the second parameter (resultSelector) in the overload:
var directory = people
   .SelectMany(p => p.PhoneNumbers,
               (parent, child) => new { parent.Name, child.Number });

عرض حي على .NET





linq