බහු තීරු අනුව සමූහය


988

LINQ හි ​​GroupBy බහු තීරු කරන්නේ කෙසේද?

SQL හි මෙයට සමාන දෙයක්:

SELECT * FROM <TableName> GROUP BY <Column1>,<Column2>

මෙය LINQ බවට පරිවර්තනය කරන්නේ කෙසේද:

QuantityBreakdown
(
    MaterialID int,
    ProductID int,
    Quantity float
)

INSERT INTO @QuantityBreakdown (MaterialID, ProductID, Quantity)
SELECT MaterialID, ProductID, SUM(Quantity)
FROM @Transactions
GROUP BY MaterialID, ProductID

Answers:


1229

නිර්නාමික වර්ගයක් භාවිතා කරන්න.

උදා

group x by new { x.Column1, x.Column2 }

31
ඔබ නිර්නාමික වර්ග සමඟ කාණ්ඩගත කිරීමට අළුත් නම්, මෙම උදාහරණයේ ඇති 'නව' මූල පදය භාවිතා කිරීම මැජික් කරයි.
ක්‍රිස්

8
mvc සමඟ nHibernate සමඟ dll ගැටළු සඳහා දෝෂයක් ඇතිවීම. GroupBy විසින් විසඳන ලද ගැටළුව (x => නව {x.Column1, x.Column2}, (යතුර, සමූහය) => නව {Key1 = key.Column1, Key2 = key.Column2, Result = group.ToList ()});
මිලාන්

මේ අවස්ථාවේ දී මම සිතුවේ නව වස්තූන් යොමු කිරීම හා සැසඳීමෙන් ය, එබැවින් ගැලපීමක් නැත - ගොරෝසු නැත.
හොගෝ

5
O හොගෝ නිර්නාමික ටයිප් කළ වස්තූන් තමන්ගේම සමාන හා GetHashCode ක්‍රම ක්‍රියාත්මක කරයි.
බයිරන් කරස්කෝ

ඔබ ලින්ක් වෙත නව වූ විට ප්‍රතිදාන දත්ත ව්‍යුහය දෘශ්‍යමාන කිරීම තරමක් දුෂ්කර ය. මෙය නිර්නාමික වර්ගය යතුර ලෙස භාවිතා කරන සමූහයක් නිර්මාණය කරයිද?
ජැක්

777

කාර්ය පටිපාටික නියැදිය

.GroupBy(x => new { x.Column1, x.Column2 })

වස්තුව ආපසු ලබා දෙන්නේ කුමන වර්ගයද?
mggSoft

6
@MGG_Soft එය නිර්නාමික වර්ගයක් වනු ඇත
ඇලෙක්ස්

මෙම කේතය මා වෙනුවෙන් ක්‍රියා නොකරයි: "වලංගු නොවන නිර්නාමික වර්ග ප්‍රකාශකය."
thalesfc

19
Om මේ සඳහා එය ක්‍රියාත්මක විය යුතුය. ඔබ නිර්නාමික වර්ගයක ක්ෂේත්‍ර නම් කිරීම මඟ හැරිය විට, ප්‍රක්ෂේපණයෙන් අවසානයේ ප්‍රවේශ වූ දේපල / ක්ෂේත්‍රයේ නම භාවිතා කිරීමට ඔබට අවශ්‍ය යැයි උපකල්පනය කරයි. (එබැවින් ඔබේ උදාහරණය Mo0gles ට සමාන වේ)
ක්‍රිස් පොෆෝල්

1
මගේ පිළිතුර සොයා ගත්තා. මට Column1 සහ Column2 ගුණාංග අඩංගු නව ආයතනයක් (MyViewEntity) නිර්වචනය කිරීමට අවශ්‍ය වන අතර ආපසු එන වර්ගය: IEnumerable <IGrouping <MyViewEntity, MyEntity >> සහ කණ්ඩායම් කේත ස්නිප් යනු: MyEntityList.GroupBy (myEntity => new MyViewEntity {Column1 = myEntity {Column1 = myEntity තීරුව 1, තීරුව 2 = myEntity.Column2});
අමීර් චත්‍රබාර්

475

හරි මේක ලැබුනේ:

var query = (from t in Transactions
             group t by new {t.MaterialID, t.ProductID}
             into grp
                    select new
                    {
                        grp.Key.MaterialID,
                        grp.Key.ProductID,
                        Quantity = grp.Sum(t => t.Quantity)
                    }).ToList();

76
+1 - සවිස්තරාත්මක උදාහරණයට ස්තූතියි. අනෙක් පිළිතුරේ කුඩා කොටස් ඉතා කෙටි වන අතර සන්දර්භය නොමැතිව. එසේම ඔබ සමස්ත ශ්‍රිතයක් පෙන්වයි (මෙම නඩුවේ එකතුව). ඉතා ප්රයෝජනවත්. සමස්ථ ශ්‍රිතයක් (එනම්, MAX, MIN, SUM, ආදිය) කණ්ඩායම් කිරීම සමඟ දෙපැත්තෙන්ම පොදු සිදුවීමක් ලෙස මම දකිමි.
බැරිපිකර්

මෙන්න: stackoverflow.com/questions/14189537/… , කණ්ඩායම් කිරීම තනි තීරුවක පදනම් වූ විට එය දත්ත වගුවක් සඳහා පෙන්වනු ලැබේ, එහි නම දන්නා නමුත් සමූහකරණය කළ යුතු තීරු පදනම් කර ගෙන එය කරන්නේ කෙසේද? ගතිකව ජනනය කළ යුතුද?
bg

කණ්ඩායම්කරණය පිළිබඳ සංකල්පය අවබෝධ කර ගැනීමටත්, ඒ මත සමූහය යෙදීමටත් මෙය සැබවින්ම උපකාරී වේ.
rajibdotnet

1
නියම උදාහරණය ... මම සොයන දේ. මට සමස්ථයක් පවා අවශ්‍ය විය. එබැවින් මම ලැම්බඩා සොයමින් සිටියද මෙය කදිම පිළිතුර විය.
කෙව්බෝ

157

බහු තීරු අනුව සමූහය සඳහා, ඒ වෙනුවට මෙය උත්සාහ කරන්න ...

GroupBy(x=> new { x.Column1, x.Column2 }, (key, group) => new 
{ 
  Key1 = key.Column1,
  Key2 = key.Column2,
  Result = group.ToList() 
});

ඔබට Column3, Column4 ආදිය එකතු කළ හැකි ආකාරයටම.


4
එය ඉතා ප්‍රයෝජනවත් වූ අතර තවත් බොහෝ දේ ලබා ගත යුතුය! Resultසියලුම තීරුවලට සම්බන්ධ කර ඇති සියලුම දත්ත කට්ටල අඩංගු වේ. ගොඩක් ස්තුතියි!
j00hi

1
සටහන: මට භාවිතා කිරීමට සිදු විය. ටොලිස්ට් () වෙනුවට ගණනය කළ හැකි ()
GMan

1
නියමයි, මේ සඳහා ස්තූතියි. මෙන්න මගේ උදාහරණය. GetFees විසින් IQueryable <Fee> RegistryAccountDA.GetFees (registryAccountId, fromDate, toDate) ලබා දෙන බව සලකන්න .GroupBy (x => new {x.AccountId, x.FeeName}, (key, group) => new {AccountId = key.AccountId , FeeName = key.FeeName, AppliedFee = group.Sum (x => x.AppliedFee) ?? 0M}). ලැයිස්තුගත කරන්න ();
ක්‍රේග් බී

කාණ්ඩගත නොවූ මෙම විමසුමෙන් වෙනත් තීරු ලබා ගත හැකිද? වස්තු සමූහයක් තිබේ නම්, මෙම වස්තුව තීරු දෙකකින් කාණ්ඩගත කිරීමට මා කැමතිය, නමුත් එම තීරු දෙකෙන් පමණක් නොව සියලු ගුණාංග වස්තුවෙන් ලබා ගන්න.
ෆ්‍රෙන්කි බී

33

සී # 7 සිට ඔබට වටිනාකමින් යුත් ටුපල් භාවිතා කළ හැකිය:

group x by (x.Column1, x.Column2)

හෝ

.GroupBy(x => (x.Column1, x.Column2))

2
හොඳයි, මම හිතන්නේ ඔබට අමතර දෙයක් නැති වී ඇත) අවසානයේ. ඔබ ()
StuiterSlurf

මම එය එකතු කර ඇත්තෙමි.
නේතන් ට්‍රෙගිලස්

2
.GroupBy (x => new {x.Column1, x.Column2})
සහීදුල් ඉස්ලාම් ජේමි

23

සී # 7.1 හෝ ඊට වැඩි භාවිතය Tuplesසහ Inferred tuple element names(දැනට එය ක්‍රියාත්මක වන්නේ linq to objectsප්‍රකාශන ගස් අවශ්‍ය වූ විට පමණි someIQueryable.GroupBy(...). උදා: ගිතුබ් නිකුතුව ):

// declarative query syntax
var result = 
    from x in inMemoryTable
    group x by (x.Column1, x.Column2) into g
    select (g.Key.Column1, g.Key.Column2, QuantitySum: g.Sum(x => x.Quantity));

// or method syntax
var result2 = inMemoryTable.GroupBy(x => (x.Column1, x.Column2))
    .Select(g => (g.Key.Column1, g.Key.Column2, QuantitySum: g.Sum(x => x.Quantity)));

C # 3 හෝ ඊට වැඩි භාවිතා කිරීම anonymous types:

// declarative query syntax
var result3 = 
    from x in table
    group x by new { x.Column1, x.Column2 } into g
    select new { g.Key.Column1, g.Key.Column2, QuantitySum = g.Sum(x => x.Quantity) };

// or method syntax
var result4 = table.GroupBy(x => new { x.Column1, x.Column2 })
    .Select(g => 
      new { g.Key.Column1, g.Key.Column2 , QuantitySum= g.Sum(x => x.Quantity) });

18

තදින් ටයිප් කළ කණ්ඩායම් කිරීම සඳහා ඔබට ටුපල් <> භාවිතා කළ හැකිය.

from grouping in list.GroupBy(x => new Tuple<string,string,string>(x.Person.LastName,x.Person.FirstName,x.Person.MiddleName))
select new SummaryItem
{
    LastName = grouping.Key.Item1,
    FirstName = grouping.Key.Item2,
    MiddleName = grouping.Key.Item3,
    DayCount = grouping.Count(), 
    AmountBilled = grouping.Sum(x => x.Rate),
}

4
සටහන: ලින්ක් ටු එන්ටිටීස් හි නව ටුපල් එකක් සෑදීමට සහාය නොදක්වයි
මෝඩයා

8

මෙම ප්‍රශ්නය පංති ගුණාංග අනුව කණ්ඩායම් ගැන විමසනු ලැබුවද, ඔබට ADO වස්තුවකට (ඩේටා ටේබල් වැනි) තීරු කිහිපයකින් කාණ්ඩ කිරීමට අවශ්‍ය නම්, ඔබේ "නව" අයිතම විචල්‍යයන්ට පැවරිය යුතුය:

EnumerableRowCollection<DataRow> ClientProfiles = CurrentProfiles.AsEnumerable()
                        .Where(x => CheckProfileTypes.Contains(x.Field<object>(ProfileTypeField).ToString()));
// do other stuff, then check for dups...
                    var Dups = ClientProfiles.AsParallel()
                        .GroupBy(x => new { InterfaceID = x.Field<object>(InterfaceField).ToString(), ProfileType = x.Field<object>(ProfileTypeField).ToString() })
                        .Where(z => z.Count() > 1)
                        .Select(z => z);

1
මට නව {c.Field <String> ("මාතෘකාව"), c.Field <String> ("CIF") by "යන ලින්ක් විමසුම මට කළ නොහැකි වූ අතර ඔබ මට බොහෝ කාලයක් ඉතිරි කළේය !! අවසාන විමසුම වූයේ: "c කාණ්ඩය නව {titulo = c.Field <String> (" මාතෘකාව "), cif = c.Field <String> (" CIF ")}"
netadictos

4
.GroupBy(x => x.Column1 + " " + x.Column2)

Linq.Enumerable.Aggregate()මේ සමඟ සංයෝජනය වීමෙන් ගතික ගුණාංග ගණනකින් කාණ්ඩගත කිරීමට පවා ඉඩ ලබා දේ : propertyValues.Aggregate((current, next) => current + " " + next).
කයි හාර්ට්මන්

3
ඕනෑම කෙනෙකුට ගෞරවය ලබා දීමට වඩා මෙය හොඳ පිළිතුරකි. තීරුව 1 වෙනස් වන අවස්ථාවන් සඳහා එකම තීරුව 2 තීරුවට එකතු කරන ලද සංයෝජන අවස්ථා තිබේ නම් එය ගැටළු සහගත විය හැකිය ("ab" "cde" "abc" "de" හා ගැලපේ). එයින් කියැවෙන්නේ ඔබට ගතික වර්ගයක් භාවිතා කළ නොහැකි නම් මෙය කදිම විසඳුමක් වන බැවින් ඔබ කණ්ඩායමට පසුව වෙන වෙනම ප්‍රකාශන මගින් ලැම්බඩස් කලින් ඉදිකරන බැවිනි.
බ්‍රැන්ඩන් බාර්ක්ලි

3
"ab" "cde" ඇත්ත වශයෙන්ම "abc" "de" සමඟ නොගැලපේ, එබැවින් අතර ඇති හිස්.
කායි හාර්ට්මන්

1
"abc de" "" සහ "abc" "de" ගැන කුමක් කිව හැකිද?
ඇල්බට්කේ




1

සැලකිල්ලට ගත යුතු කරුණක් නම්, ඔබට ලැම්බඩා ප්‍රකාශන සඳහා වස්තුවක් යැවිය යුතු අතර පන්තියක් සඳහා උදාහරණයක් භාවිතා කළ නොහැක.

උදාහරණයක්:

public class Key
{
    public string Prop1 { get; set; }

    public string Prop2 { get; set; }
}

මෙය සම්පාදනය කරන නමුත් එක් චක්‍රයකට එක් යතුරක් ජනනය කරනු ඇත .

var groupedCycles = cycles.GroupBy(x => new Key
{ 
  Prop1 = x.Column1, 
  Prop2 = x.Column2 
})

ඔබට ප්‍රධාන ගුණාංග නම් කර ඒවා නැවත ලබා ගැනීමට අවශ්‍ය නැතිනම් ඔබට ඒ වෙනුවට මෙය කළ හැකිය. මෙය GroupByනිවැරදිව ඔබට ප්‍රධාන ගුණාංග ලබා දෙනු ඇත.

var groupedCycles = cycles.GroupBy(x => new 
{ 
  Prop1 = x.Column1, 
  Prop2= x.Column2 
})

foreach (var groupedCycle in groupedCycles)
{
    var key = new Key();
    key.Prop1 = groupedCycle.Key.Prop1;
    key.Prop2 = groupedCycle.Key.Prop2;
}

0

සඳහා වොලිබෝල් හා නිර්නාමික / ලැම්ඩා :

query.GroupBy(Function(x) New With {Key x.Field1, Key x.Field2, Key x.FieldN })
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.