I am using latest version of mongodb with MongoDB driver for C#. I created a little example, which should explain my problem. My goal ist to make some conditional Count(), conditional First() or an Average() with with filter. None of it works.
What would be the best solution to this problem. Thanks for any hint
class MealDocument
{
public string name { get; set; }
public DateTime time { get; set; }
public Type type { get; set; }
public double calorie { get; set; }
public enum Type { breakfast, launch, dinner }
}
class MealAnalysis
{
public string name { get; set; }
public int numberOfBreakfast { get; set; }
public DateTime firstLaunch { get; set; }
public double averageDinnerCalorie { get; set; }
}
public void Test()
{
var collection = Database.GetCollection<MealDocument>("meal_test");
collection.InsertMany(new MealDocument[] {
new MealDocument { name = "Thomas", type = MealDocument.Type.breakfast, calorie = 100, time = new DateTime(2017,8,1) },
new MealDocument { name = "Thomas", type = MealDocument.Type.breakfast, calorie = 100, time = new DateTime(2017,8,2) },
new MealDocument { name = "Thomas", type = MealDocument.Type.launch, calorie = 800, time = new DateTime(2017,8,3) },
new MealDocument { name = "Thomas", type = MealDocument.Type.dinner, calorie = 2000, time = new DateTime(2017,8,4) },
new MealDocument { name = "Peter", type = MealDocument.Type.breakfast, calorie = 100, time = new DateTime(2017,8,5) },
new MealDocument { name = "Peter", type = MealDocument.Type.launch, calorie = 500, time = new DateTime(2017,8,6) },
new MealDocument { name = "Peter", type = MealDocument.Type.dinner, calorie = 800, time = new DateTime(2017,8,7) },
new MealDocument { name = "Paul", type = MealDocument.Type.breakfast, calorie = 200, time = new DateTime(2017,8,8) },
new MealDocument { name = "Paul", type = MealDocument.Type.launch, calorie = 600, time = new DateTime(2017,8,9) },
new MealDocument { name = "Paul", type = MealDocument.Type.launch, calorie = 700, time = new DateTime(2017,8,10) },
new MealDocument { name = "Paul", type = MealDocument.Type.dinner, calorie = 1200, time = new DateTime(2017,8,11) }
});
var analysis = collection.Aggregate()
.Group(
doc => doc.name,
group => new MealAnalysis
{
name = group.Key,
// !!!! The condition in the Count() gets ignored
numberOfBreakfast = group.Count(m => m.type == MealDocument.Type.breakfast),
// !!!! Exception --> Not supported
averageDinnerCalorie = group.Where(m => m.type == MealDocument.Type.dinner).Average(m => m.calorie),
// !!!! Exception --> Not supported
firstLaunch = group.First(m => m.type == MealDocument.Type.launch).time
}
);
var query = analysis.ToString();
var result = analysis.ToList();
}
I spent a few hours and I can't get driver to work as you need it to. Although I didn't come up with correct solution this is closest I got. I am not a big fan of this solution because it calculates a lot you don't need but it might work good enough if Db is not that large and until you find solution to problem.
var groupRes = collection.Aggregate()
.Group
(
x => new { x.name, x.type },
g => new
{
key = g.Key,
count = g.Count(),
averageCalorie = g.Average(y => y.calorie),
first = g.First().time
}
)
.ToList();
var paulStat = new MealAnalysis()
{
name = "Paul",
averageDinnerCalorie = groupRes.FirstOrDefault(x => (x.key.name == "Paul" && x.key.type == Type.dinner)).averageCalorie,
numberOfBreakfast = groupRes.FirstOrDefault(x => (x.key.name == "Paul" && x.key.type == Type.breakfast)).count,
firstLaunch = groupRes.FirstOrDefault(x => (x.key.name == "Paul" && x.key.type == Type.launch)).first
};
as you can see I calculate stuff you need for each enum and then construct for each person his MealAnalysis. Maybe someone finds solution you need.
Good Luck!
Related
In my Application Users can Have Multiple Roles , I Want To Convert List of Roles To One Common Role Object For Apply Permission
How i can handle convert List to Common role ?
public class Role
{
public boolData ListBools { get; set; }
public ListId ListIds { get; set; }
}
public class boolData
{
public bool CanSale { get; set; }
public bool CanBuy { get; set; }
}
public class ListId
{
public IEnumerable<Int64> Product { get; set; }
public IEnumerable<Int64> Formula { get; set; }
}
For Example this User have two Roles I Want to exucute common to one role object
IEnumerable<Role> UserRoles = new List<Role>()
{
new Role(){ListBools = new boolData()
{
CanBuy = false,
CanSale = true
},
ListIds = new ListId()
{
Product = new List<long>(){1,4,58},
Formula = new List<long>(){2,7,}
}
},
new Role(){ListBools = new boolData()
{
CanBuy = true,
CanSale = true
},
ListIds = new ListId()
{
Product = new List<long>(){1,6,70},
Formula = new List<long>(){2,9,}
}
},
};
must convert To
Role Result = new Role()
{
ListBools = new boolData()
{
CanBuy = true,
CanSale = true
},
ListIds = new ListId()
{
Product = new List<long>() { 1, 4, 6, 58, 70 },
Formula = new List<long>() { 2, 7, 9, }
}
};
You can use combination of Any and SelectMany() from Linq,
Like,
var Result = new Role()
{
ListBools = new boolData()
{
CanBuy = UserRoles.Any(x => x.ListBools.CanBuy),
CanSale = UserRoles.Any(x => x.ListBools.CanSale)
},
ListIds = new ListId()
{
Product = UserRoles.SelectMany(x => x.ListIds.Product).Distinct(),
Formula = UserRoles.SelectMany(x => x.ListIds.Formula).Distinct()
}
};
For list of Formulas and Products you can use SelectMany + Distinct:
Role sum = new Role
{
ListBools = new boolData()
{
CanBuy = true,
CanSale = true
},
ListIds = new ListId
{
Formula = UserRoles.SelectMany(x => x.ListIds.Formula).Distinct().ToList(),
Product = UserRoles.SelectMany(x => x.ListIds.Product).Distinct().ToList()
}
};
I'm not suer how ListBools should be produced .... Maybe you should group all rules and join Formula/Product per boolData
You could use this code:
SelectMany merges many Product/Formula lists into one
Distinct removes duplicates
OrderBy ensures a ascending order
Any checks if at least one CanBuy/CanSale property is true
Btw - I agree with the comments that say the Class/Property names could be be
var products = UserRoles.SelectMany(m => m.ListIds.Product).Distinct().OrderBy(m => m).ToList();
var formulas = UserRoles.SelectMany(m => m.ListIds.Formula).Distinct().OrderBy(m => m).ToList();
var anyCanBuy = UserRoles.Any(m => m.ListBools.CanBuy);
var anyCanSale = UserRoles.Any(m => m.ListBools.CanSale);
Role Result = new Role()
{
ListBools = new boolData()
{
CanBuy = anyCanBuy,
CanSale = anyCanSale,
},
ListIds = new ListId()
{
Product = products,
Formula = formulas,
}
};
In this contrived example, which closely resembles my real-world problem, I have a data set coming from an external source. Each record from the external source takes the following form:
[Classification] NVARCHAR(32),
[Rank] INT,
[Data] NVARCHAR(1024)
I am looking to build an object where the Rank and Data are patched into a single instance of a response object that contains list properties for the three hard-coded Classification values, ordered by Rank.
I have something that works, but I can't help but think that it could be done better. This is what I have:
public static void Main()
{
IEnumerable<GroupingTestRecord> records = new List<GroupingTestRecord>
{
new GroupingTestRecord { Classification = "A", Rank = 1, Data = "A1" },
new GroupingTestRecord { Classification = "A", Rank = 2, Data = "A2" },
new GroupingTestRecord { Classification = "A", Rank = 3, Data = "A3" },
new GroupingTestRecord { Classification = "B", Rank = 1, Data = "B1" },
new GroupingTestRecord { Classification = "B", Rank = 2, Data = "B2" },
new GroupingTestRecord { Classification = "B", Rank = 3, Data = "B3" },
new GroupingTestRecord { Classification = "C", Rank = 1, Data = "C1" },
new GroupingTestRecord { Classification = "C", Rank = 2, Data = "C2" },
new GroupingTestRecord { Classification = "C", Rank = 3, Data = "C3" },
};
GroupTestResult r = new GroupTestResult
{
A = records.Where(i => i.Classification == "A").Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank),
B = records.Where(i => i.Classification == "B").Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank),
C = records.Where(i => i.Classification == "C").Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank),
};
The source record DTO:
public class GroupingTestRecord
{
public string Classification { get; set; }
public int? Rank { get; set; }
public string Data { get; set; }
}
The destination single class:
public class GroupTestResult
{
public IEnumerable<GroupTestResultItem> A { get; set; }
public IEnumerable<GroupTestResultItem> B { get; set; }
public IEnumerable<GroupTestResultItem> C { get; set; }
}
The distination child class:
public class GroupTestResultItem
{
public int? Rank { get; set; }
public string Data { get; set; }
}
Ouput
{
"A":[
{
"Rank":1,
"Data":"A1"
},
{
"Rank":2,
"Data":"A2"
},
{
"Rank":3,
"Data":"A3"
}
],
"B":[
{
"Rank":1,
"Data":"B1"
},
{
"Rank":2,
"Data":"B2"
},
{
"Rank":3,
"Data":"B3"
}
],
"C":[
{
"Rank":1,
"Data":"C1"
},
{
"Rank":2,
"Data":"C2"
},
{
"Rank":3,
"Data":"C3"
}
]
}
Fiddle
Is there a better way to achieve my goal here?
The same JSON output was achieved using GroupBy first on the Classification and applying ToDictionary on the resulting IGrouping<string, GroupingTestRecord>.Key
var r = records
.GroupBy(_ => _.Classification)
.ToDictionary(
k => k.Key,
v => v.Select(j => new GroupTestResultItem { Rank = j.Rank, Data = j.Data, }).OrderBy(k => k.Rank).ToArray()
);
var json = JsonConvert.SerializeObject(r);
Console.WriteLine(json);
which should easily deserialize to the destination single class (for example on a client)
var result = JsonConvert.DeserializeObject<GroupTestResult>(json);
is it possible to get the top level result into a GroupTestResult object?
Build the result from the dictionary
var result = new GroupTestResult {
A = r.ContainsKey("A") ? r["A"] : Enumerable.Empty<GroupTestResultItem>();,
B = r.ContainsKey("B") ? r["B"] : Enumerable.Empty<GroupTestResultItem>();,
C = r.ContainsKey("C") ? r["C"] : Enumerable.Empty<GroupTestResultItem>();,
};
Or this
var result = records.GroupBy(x => x.Classification)
.ToDictionary(x => x.Key, x => x.Select(y => new {y.Rank, y.Data})
.OrderBy(y => y.Rank));
Console.WriteLine(JsonConvert.SerializeObject(result));
Full Demo Here
How do I need to write to iterate through the results of each of those three initial lists in order to return a single List. Title is the grouping value.
var invoiced = new List<Anonim>
{
new Anonim {Category = 1, Title = "Legal", Amount = 20},
new Anonim {Category = 2, Title = "Accounting", Amount = 10}
}
var settled = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 10}
}
var credit = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 30},
new Anonim {Category = 2, Title = "Accounting", Amount = 20}
}
var result = new List<Result> {
new Result {Title = credit.Title, Invoiced = invoiced.Amount, Settled = settled.Amount, SumAmount = credit.Amount + settled.Amount + invoiced.Amount },
new Result {Title = credit.Title, Invoiced = invoiced.Amount, Settled = settled.Amount, SumAmount = credit.Amount + settled.Amount + invoiced.Amount }
}
public class Result
{
public string Title { get; set; }
public decimal Credit { get; set; }
public decimal Invoiced { get; set; }
public decimal Settled { get; set; }
public decimal SumAmount { get; set; }
}
public class Anonim {
public int Category { get; set; }
public string Title { get; set; }
public decimal Amount { get; set; }
}
SumAmount is the sum of Invoiced, settled, credit of each item
It's a little unclear what you want to happen, but assuming you want to group by the Title property, here's one method. First you project each list into the Result class, making sure to set the relevant properties for each one, union them together into a big list and then group them to get the totals:
var groupedResults = invoiced.Select(i => new Result
{
Title = i.Title,
Invoiced = i.Amount
}).Union(settled.Select(i => new Result
{
Title = i.Title,
Settled = i.Amount
})).Union(credit.Select(i => new Result
{
Title = i.Title,
Credit = i.Amount
}));
var result = groupedResults
.GroupBy(r => r.Title)
.Select(g => new Result
{
Title = g.Key,
Invoiced = g.Sum(r => r.Invoiced),
Settled = g.Sum(r => r.Settled),
Credit = g.Sum(r => r.Credit),
SumAmount = g.Sum(r => r.Invoiced+r.Settled+r.Credit)
});
If I understood you correctly, this is something you want, however this is inefficient due to numerous collection traversals. Maybe #DavidG solution will be more performant.
var groupedSum = invoiced.Union(settled).Union(credit).GroupBy(g => g.Title).Select(g => new Result
{
Title = g.Key,
Credit = credit.Where(c => c.Title == g.Key).Sum(c => c.Amount),
Settled = settled.Where(c => c.Title == g.Key).Sum(c => c.Amount),
Invoiced = invoiced.Where(c => c.Title == g.Key).Sum(c => c.Amount),
SumAmount = g.Sum(i => i.Amount)
});
This is simplest I can find :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication73
{
class Program
{
static void Main(string[] args)
{
List<Anonim> invoiced = new List<Anonim>
{
new Anonim {Category = 1, Title = "Legal", Amount = 20},
new Anonim {Category = 2, Title = "Accounting", Amount = 10}
};
List<Anonim> settled = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 10}
};
List<Anonim> credit = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 30},
new Anonim {Category = 2, Title = "Accounting", Amount = 20}
};
List<Result> results = new List<Result>();
List<string> titles = invoiced.Select(x => x.Title).ToList();
titles.AddRange(settled.Select(x => x.Title).ToList());
titles.AddRange(credit.Select(x => x.Title).ToList();
titles = titles.Distinct().ToList();
foreach(string title in titles)
{
Result newResult = new Result();
results.Add(new Result);
newResult.Title = title;
newResult.Credit = credit.Where(x => x.Title == title).Sum(x => x.Amount);
newResult.Invoiced = invoiced.Where(x => x.Title == title).Sum(x => x.Amount);
newResult.Settled = settled.Where(x => x.Title == title).Sum(x => x.Amount);
newResult.SumAmount = newResult.Credit + newResult.Invoiced + newResult.Settled;
}
}
}
public class Result
{
public string Title { get; set; }
public decimal Credit { get; set; }
public decimal Invoiced { get; set; }
public decimal Settled { get; set; }
public decimal SumAmount { get; set; }
}
public class Anonim
{
public int Category { get; set; }
public string Title { get; set; }
public decimal Amount { get; set; }
}
}
var invoiced = new List<Anonim>
{
new Anonim {Category = 1, Title = "Legal", Amount = 20},
new Anonim {Category = 2, Title = "Accounting", Amount = 10}
};
var settled = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 10}
};
List<Anonim> credit = new List<Anonim> {
new Anonim {Category = 1, Title = "Legal", Amount = 30},
new Anonim {Category = 2, Title = "Accounting", Amount = 20}
};
List<Result> x = new List<Result>();
x.AddRange(invoiced.Select(y => new Result { Title = y.Title, Invoiced = y.Amount }));
x.AddRange(settled.Select(y => new Result { Title = y.Title, Invoiced = y.Amount }));
x.AddRange(credit.Select(y => new Result { Title = y.Title, Invoiced = y.Amount }));
var FinalList = x.GroupBy(a => a.Title).Select(Fn => new Result {
Title =Fn.Key,
Invoiced = Fn.Sum(a => a.Invoiced),``
Settled = Fn.Sum(a => a.Settled),
Credit = Fn.Sum(a => a.Credit),
SumAmount = Fn.Sum(a => a.Invoiced + a.Settled + a.Credit)
});
I have a question about a LINQ grouping.
I thought that grouping would be a simple matter of using the GroupBy function on the result set and specifying what to group it by. However my items appear to not be grouping together and instead are displaying as if the GroupBy function wasn't there. I want to group by the itemPk, but I'm can't seem to do it. I have tried grouping by both category.ItemFk and Item.Itempk, but no luck. Could someone give me a pointer on this?
var itemIds = items.Select(i => i.ItemId).ToList();
var itemAndCatJoin =
from item in Context.SCS_Items
join category in Context.SCS_ItemCategories
on item.ItemPk equals category.ItemFk
into temp
from category in temp.DefaultIfEmpty()
select new ExportItemTable
{
Category = category,
Item = item
};
return itemAndCatJoin.Where(i => itemIds.Contains(i.Item.ItemPk))
.GroupBy(n => new {n.Item, n.Category})
.Select(i => new ExportableItem
{
ItemPk = i.Key.Item.ItemPk,
Name = i.Key.Item.Name,
Description = i.Key.Item.Description,
Price = i.Key.Item.Price,
Category = i.Key.Category.Category.Category_Name,
GLDepartment = i.Key.Category.GL_Department.Name ?? "",
GLName = i.Key.Category.GL_Name.Name ?? "",
StartDate = i.Key.Item.StartDate,
EndDate = i.Key.Item.EndDate,
FiscalYear = i.Key.Item.SCS_FiscalYear.Name,
School = i.Key.Item.School != null ? i.Key.Item.School.School_Name : i.Key.Item.Board.Board_Name,
Beneficiary = i.Key.Item.SCS_Beneficiary.Name,
Quantity = i.Key.Item.MaxQuantity,
Deleted = i.Key.Item.DeletedFlag,
OptionalStudents = i.Key.Item.SCS_Attachments.Where(a => !a.IsRequired).SelectMany(a => a.SCS_StudentAttachments).Where(s => !s.DeletedFlag).Select(s => s.StudentFk).Distinct().Count(),
RequiredStudents = i.Key.Item.SCS_Attachments.Where(a => a.IsRequired).SelectMany(a => a.SCS_StudentAttachments).Where(s => !s.DeletedFlag).Select(s => s.StudentFk).Distinct().Count(),
IsPublic = i.Key.Item.IsPublic,
AllowRecurring = i.Key.Item.AllowRecurringPayments,
EffectiveCutoff = i.Key.Item.SCS_Attachments.Where(a => !a.DeletedFlag && a.CourseDropCutoff.HasValue).Select(a => a.CourseDropCutoff).OrderBy(a => a).FirstOrDefault(),
CreatedDate = i.Key.Item.CreatedDate
}).OrderBy(i => i.ItemPk).ToList();
}
your groupbyy is indeed doing nothing for you, you need to tell the groupby what to group by....
like
.GroupBy(n => n.Category)
Here is a simple example to your grouping question:
class Program
{
static void Main()
{
var allItems = GetAllItems();
var groups = from item in allItems
group item by item.Category
into newGroup
select newGroup;
foreach (var group in groups)
{
Console.WriteLine($"\nCategory: {group.Key}");
foreach (var item in group)
{
Console.WriteLine($"{item.Name}: {item.Price}");
}
}
Console.ReadLine();
}
static List<Category> GetAllCategories()
{
return new List<Category>()
{
new Category() { Id = 1, Name = "Programming Books" },
new Category() { Id = 2, Name = "Fiction Books" }
};
}
static List<Item> GetAllItems()
{
return new List<Item>()
{
new Item() { Id = 1, Name = "Embedded Linux", Category = 1, Price = 9.9 },
new Item() { Id = 2, Name = "LINQ In Action", Category = 1, Price = 36.19 },
new Item() { Id = 3, Name = "C# 6.0 and the .NET 4.6 Framework", Category = 1, Price = 40.99 },
new Item() { Id = 4, Name = "Thinking in LINQ", Category = 1, Price = 36.99 },
new Item() { Id = 5, Name = "The Book Thief", Category = 2, Price = 7.99 },
new Item() { Id = 6, Name = "All the Light We Cannot See", Category = 2, Price = 16.99 },
new Item() { Id = 7, Name = "The Life We Bury", Category = 2, Price = 8.96 }
};
}
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int Category { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
This example is simple enough for anyone new to LINQ. I am sure you can make some adjustment to make it work for your specific issue. Hope this will help.
I have a one to many r/ship between two tables. I am using Entity Frameworks 6. Table 1 is called "Vote" and table 2 is "VoteInfo". The Vote table has an attribute called "VoteYear" and the VoteInfo table has an attribute called "VoterId". There could be many vote records in a given year but a voter can only vote once per a vote record. My goal is to return a list of all votes
in a year that a voter has voted on. I want to include the information from the VoteInfo table as part of this list. This is how I want to return my result:
<Vote>
<VoteDate>5/21/2015</VoteDate>
<VoteYear>2015</VoteYear>
<VoteInfo>
<VoterId>1</VoterId>
<VoteValue>Yes</VoteValue>
</VoteInfo>
</Vote>
<Vote>
<VoteDate>4/21/2015</VoteDate>
<VoteYear>2015</VoteYear>
<VoteInfo>
<VoterId>1</VoterId>
<VoteValue>Yes</VoteValue>
</VoteInfo>
</Vote>
<Vote>
<VoteDate>3/21/2015</VoteDate>
<VoteYear>2015</VoteYear>
<VoteInfo>
<VoterId>1</VoterId>
<VoteValue>No</VoteValue>
</VoteInfo>
</Vote>
I tried this but not working:
public IQueryable<Vote> GetVoterRecord(string Year, string VoterId)
{
return _dbCtx.Vote.Include("VoteInfo")
.Where(v => v.VoteYear == Year && v.VoteInfo.Any(i => i.VoterId == VoterId));
}
The sample code satisfying OP's conditions is the following.
public class VotesContext : DbContext {
public DbSet<Vote> Votes { get; set; }
public DbSet<VoteInfo> VoteInfos { get; set; }
}
public class Vote {
public int VoteId { get; set; }
public string VoteYear { get; set; }
public virtual ICollection<VoteInfo> VoteInfo { get; set; }
}
public class VoteInfo {
public int VoteInfoId { get; set; }
public string VoterId { get; set; }
}
Then the code
var v1 = db.Votes.Add(new Vote { VoteYear = "2001", });
var v2 = db.Votes.Add(new Vote { VoteYear = "2001", });
var v3 = db.Votes.Add(new Vote { VoteYear = "2002", });
var v4 = db.Votes.Add(new Vote { VoteYear = "2003", });
v1.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "1", }, new VoteInfo { VoterId = "3", }, };
v2.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "1", }, new VoteInfo { VoterId = "4", }, };
v3.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "2", }, };
//v1.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "3", }, };
//v2.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "4", }, };
db.SaveChanges();
// Each record corresponds to a vote in 2001 where voter #1 has voted.
// VoteInfo for each voter in this vote is included.
var votesIn2001With1 = db.Votes
.Where(x1 =>
x1.VoteYear == "2001" &&
x1.VoteInfo.Any(x2 => x2.VoterId == "1"))
.Select(x => new {
vote = x,
voteInfo = x.VoteInfo.ToList(),
})
.ToList();
// Each record corresponds to a vote in 2001 where voter #1 has voted.
// VoteInfo only for voter #1 is included.
var votesOf1In2001 = db.Votes
.Where(x1 =>
x1.VoteYear == "2001" &&
x1.VoteInfo.Any(x2 => x2.VoterId == "1"))
.Select(x1 => new {
vote = x1,
voteInfo = x1.VoteInfo
.Where(x2 => x2.VoterId == "1")
.ToList(),
})
.ToList();
does exactly the necessary things.