Query entity and return back a dictionary - c#

I'm trying to query a view (entity) from the database and return back a dictionary. There are duplicates in the view so I tried groupby and I can't figure it out.
var queryresults = db.MyView.Where(x => x.year == myYear)
.GroupBy(g => new { g.myCode, g.myCodeName})
.ToDictionary(d => d.myCode, d => d.myCodeName);

You should group by dictionary key property if you want to avoid duplicate keys error. Then you can select code name of first item in each group as dictionary entry value:
var queryresults =
db.MyView.Where(x => x.year == myYear)
.GroupBy(x => x.myCode)
.ToDictionary(g => g.Key, g => g.First().myCodeName);

Related

convert dictionary to list model

var entity = await _abcRepository.get(Id);
var X = entity.GroupBy(c => c.number).Where(grp => grp.Count() == 1).Take(10).ToList();
in images you see [0] and inside of it one more [0].
How can I get that model value.
X[0][0] is not working.
X.Value is not working.
I need to convert that dictionary to model.
Use .Select to normalize aggregation as per your wish.
var X = entity.GroupBy(c => c.number).Where(grp => grp.Count() == 1)
.Select(group => new { GroupKey = group.Key, Items = group.ToList() })
.Take(10).ToList();
You could try something like this:
var entity = await _abcRepository.get(Id);
var results = entity.GroupBy(c => c.number)
.Where(grp => grp.Count() == 1)
.Take(10)
.ToDictionary(grp => grp.Key, grp => grp.First());
Essentially, the lambda you pass in Where method certifies that the groups are created contains only one item. That being said, you can use the First on each group to fetch that one element.

How to convert a iterable variable to single item with groupby in C#

I have a sql query which returns a list of rows from site table(a site belongs to a company);
Dictionary<int, List<Site>> contactSites = null;
var sites= _dataContext.tContacts
.Where(c => c.ContactId == userId)
.SelectMany(c => c.Sites);
I want to group by them with company id and add them to a dictionary;
contactSites = sites.GroupBy(x => x.CompanyId).ToDictionary(x => x.Key, x => x.ToList());
Since I select Many from the query I get casting issue..
How can I overcome this?

Sorting a dictionary via multiple parameters

I have a dictionary IDictionary answersDictionary<Country, List<Answer>>, where Country contains information on country and List<Answer> is a list of Answer objects, which have a property State that can be final, draft, comment.
I need to sort the dictionary in a way, that its sorted by:
Number of draft answers for country
Number of comment answers for country
By Country.Name
And, at the end get only the keys of the dictionary.
I have done the following:
IDictionary<Country, List<Answer>> answersDictionary = Database.Answer
.GroupBy(a => a.Country).ToDictionary(d => d.Key, d => d.ToList());
answersDictionary.OrderByDescending(d => d.Value.Where(a => a.State == AnswerState.Draft).Count())
.ThenByDescending(d => d.Value.Where(a => a.State == AnswerState.Comment).Count())
.ThenBy(d => d.Key.Name);
And at the end List<Country> finalResult=answersDictionary.Keys;
But, the results are not correct, as they are returned sorted only by Draft and in ascending order. Any suggestions, what's the issue?
You have to assign your second query to a variable. Try this:
IDictionary<Country, List<Answer>> answersDictionary = Database.Answer
.GroupBy(a => a.Country).ToDictionary(d => d.Key, d => d.ToList());
var answerDict = answersDictionary.OrderByDescending(d => d.Value.Count(a => a.State == AnswerState.Draft))
.ThenByDescending(d => d.Value.Count(a => a.State == AnswerState.Comment))
.ThenBy(d => d.Key.Name)
.ToDictionary(d => d.Key, d => d.Value);
List<Country> finalResult = answerDict.Keys.ToList();

How to order groupBy items

Having this Linq query which returns grouping of 4 DateTime:
IEnumerable<IGrouping<DateTime, QuoteSnapshotModel>> lista = (from q in quoteModeList
where q.QuoteTradeType == "Q"
select q).GroupBy(n => n.ExceriseDate);
How can I order the groups by DateTime and get only the first group?
meaning **List<QuoteSnapshotModel>**
Also, how can I get only the second List<QuoteSnapshotModel> (according to DateTime)
Try this:
for this you have to create a list<QuoteSnapshotModel> within class QuoteSnapshotModel.
int record = 1;
List<QuoteSnapshotModel> result =
quoteModeList
.Where(x => x.QuoteTradeType == "Q")
.GroupBy(x => x.ExceriseDate,
(a, b) => new QuoteSnapshotModel
{
ExceriseDate = a,
ListQuoteSnapshotModel = b.ToList()
})
.OrderByDescending(t => t.ExceriseDate)
.Skip(record - 1).Take(1).ToList();
Update
You can use only the first group
List<QuoteSnapshotModel> list =quoteModeList.Where(x=>x.QuoteTradeType =="Q")
.GroupBy(x => x.ExceriseDate)
.OrderBy(x=>x.Key)
.FirstOrDefault().Select(x=>x.QuoteTradeType).ToList();
You can use only the second group
List<QuoteSnapshotModel> list =quoteModeList.Where(x=>x.QuoteTradeType =="Q")
.GroupBy(x => x.ExceriseDate)
.OrderBy(x=>x.Key)
.Skip(1).First().Select(x=>x.QuoteTradeType).ToList()
How can I order the groups by DateTime
.OrderBy(g => g.Key) or .OrderBy(g => g.First().ExerciseDate)
and get only the first group?
.First() (or .FirstOrDefault() if it's possible there are 0 groups)
how can I get only the second List (according to DateTime)
.Skip(1).Take(1) or .ElementAt(1) or .Skip(1).First()
Putting it all together:
IEnumerable<IGrouping<DateTime, QuoteSnapshotModel>> lista = (
from q in quoteModeList
where q.QuoteTradeType == "Q"
select q
).GroupBy(n => n.ExerciseDate);
IList<QuoteSnapshotModel> firstQuote = lista.OrderBy(x => x.Key).Select(x => x.ToList()).FirstOrDefault();
IList<QuoteSnapshotModel> secondQuote = lista.OrderBy(x => x.Key).Skip(1).Select(x => x.ToList()).FirstOrDefault();

C# Convert columns to rows using linq?

I have the following table structure. I want to retrieve value corresponding to key for each group name and insert it store it sequentially in a model class
the table data has been read using a ExecuteQuery and stored in a list of class object, in the below example I will have 4 rows returned. I need to convert it into 2 rows, the column values coming in as rows.
I have the following code written now, But is there any other way to verify it without explicitly checking for say Key == "GroupSpecificProperty1"?
If there is a 3rd category added later, I shouldn't have to modify this code
Result = results.GroupBy(p => p.GroupName )
.Select(g => new FinalModel()
{
GroupName = g.Select(p => p.GroupName ).FirstOrDefault(),
GroupSpecificProperty1 = g.Where(q => q.Key == "GroupSpecificProperty1").Select(v => v.Value).Cast<string>().FirstOrDefault(),
GroupSpecificProperty2= g.Where(q => q.Key == "GroupSpecificProperty2").Select(v => v.Value).Cast<string>().FirstOrDefault(),
}).ToList();
results.GroupBy(p => p.GroupName)
.Select(g => new FinalModel
{
GroupName = g.Key,
Properties = g.ToDictionary(item => item.Key, item=> item.Value)
});
And in the case that for a given GroupName the keys are not unique and you'd want to avoid a "key already exists" exception then you can:
results.GroupBy(p => p.GroupName)
.Select(g => new FinalModel
{
GroupName = g.Key,
Properties = g.GroupBy(item => item.key)
.ToDictionary(innerGroup => innerGroup.Key,
innerGroup => innerGroup.Select(innerItem => innerItem.Value))
});
Then of course you can also replace the outer/inner dictionary with a LookUp if it fits your needs better.

Categories