i have a datatable in which look like this
basically i want it to be group by column featurename(distinct) in which it should sum in effort and complete column
specify all the featureid,featurename comma sepratedcount of the featureid
assigned to comman seprated
now i want datatable to be look like this
don't know how to use the count
code
var result5= dtTaskandBugs.AsEnumerable().GroupBy(x => x["Functional Area"])
.Select(item => new
{
FunctionalArea = item.Key,
Completedsum = item.Sum(y => Convert.ToDecimal(y["Completed"])),
effortsum = item.Sum(z => Convert.ToDecimal(z["effort"])),
storyids = string.Join(",", item.Select(a => a["Storyid"]).Distinct()),
storiesename= string.Join(",", item.Select(b => b["StoryName"]).Distinct()),
Featureid = string.Join(",", item.Select(c => c["Featureid"]).Distinct()),
Featurename= string.Join(",", item.Select(d => d["FeatureName"]).Distinct()),
});
With Count() you will get count of grouped value.
Try with Linq like this:
from s in dtTaskandBugs.AsEnumerable()
group s by s.Field<string>("Functional Area")
into grp
orderby grp.Key
select new {
FunctionalArea = grp.Key,
Completedsum = grp.Sum(y => Convert.ToDecimal(y["Completed"])),
effortsum = grp.Sum(z => Convert.ToDecimal(z["effort"])),
storyids = string.Join(",", grp.Select(a => a["Storyid"]).Distinct()),
storiesename= string.Join(",", grp.Select(b => b["StoryName"]).Distinct()),
Featureid = string.Join(",", grp.Select(c => c["Featureid"]).Distinct()),
Featurename= string.Join(",", grp.Select(d => d["FeatureName"]).Distinct()),
Count = grp.Count() // <----------------
};
Just write item.count() and you will get count of grouped values,
Related
having some trouble writing the following code to some nicer/less lines :)
any one have the good solution?
//custom implementation for popular filters
var popularFilter = new Dictionary<string, int>();
foreach (var car in allFilteredCars)
{
foreach (var offering in car.Offerings)
{
if (popularFilter.ContainsKey(offering))
popularFilter[offering] = popularFilter[offering] + 1;
else
popularFilter.Add(offering, 1);
}
}
categories.Add(new Category
{
Name = "popular",
Code = "popular",
Values = popularFilter.Select(p => new Value
{
Code = p.Key,
Name = p.Key,
Count = p.Value
}).ToList()
});
If it is possible i want i directly to add it in the categories list.
car.offerings = list<string>
so basicly something like:
Categories.Add(allFilteredCars.SelectMany(
c => c.Offerings.Select(
o => new {
something magical here}
.Select(a =>
new Category{
code.. etc etc..}
));
It looks like you just want to do a SelectMany to get the offerings, then group them and select the Count.
categories.Add(new Category
{
Name = "popular",
Code = "popular",
Values = allFilteredCars.SelectMany(c => c.Offerings)
.GroupBy(o => o)
.Select(grp => new Value
{
Code = grp.Key,
Name = grp.Key,
Count = grp.Count()
}).ToList()
});
Your non linq code already looks quite fine.
You can create your dictionary with linq by using a GroupBy & ToDictionary:
var dictionary = offerings
.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
I have a table of lessons, and I want to perform a text search over several fields of it. However the search should be ordered: for example lesson have a Keywords field and Description field. The search should give a priority over values found by Keywords. Everything should be also ordered by date but only after the priority is considered.
I'm also using ToPagedList() in the end from https://github.com/troygoode/PagedList (I think it just uses Skip() and Top() to manage pages)
This is what I have so far:
string[] word = /*Search words*/
var data = db.LessonsLearneds.Where(dbRecord => words.Any(word =>
dbRecord.SearchKeywords.StartsWith(word + ",") ||
dbRecord.SearchKeywords.Contains("," + word + ",") ||
dbRecord.SearchKeywords.EndsWith("," + word)))
.Select(x => new { Record = x, Order = 1 });
data = data.Union(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Title.Contains(word)))
.Select(x => new { Record = x, Order = 2 }));
data = data.Union(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Description.Contains(word)))
.Select(x => new { Record = x, Order = 3}));
data = data.Union(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Lesson.Contains(word)))
.Select(x => new { Record = x, Order = 4 }));
return data
.Distinct()
.OrderBy(x => x.Order)
.ThenByDescending(x => x.Record.Date)
.Select(x => x.Record)
.ToPagedList(pageNumber, pageSize);
Overall this code does almost what I want, except of Distinct(). Each union here can retrieve the same record, so I may receive it several times, and Distinct() does not forces the uniqueness because of virtual Order field. I cannot put Distinct after Select(x => x.Record) because of ToPagedList(..) which requires the set to be ordered (results in: The method 'Skip' is only supported for sorted input in LINQ to Entities. exception)
Any ideas?
I have one so far: to add Order field after I Distinct, but this means that I will have to write those Contains checks twice which I think is very ugly solution.
First, since you are projecting unique records due to the different Order value, replace the Union operator with Concat (which is the LINQ equivalent of the SQL UNION ALL).
string[] word = /*Search words*/
var data = db.LessonsLearneds.Where(dbRecord => words.Any(word =>
dbRecord.SearchKeywords.StartsWith(word + ",") ||
dbRecord.SearchKeywords.Contains("," + word + ",") ||
dbRecord.SearchKeywords.EndsWith("," + word)))
.Select(x => new { Record = x, Order = 1 });
data = data.Concat(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Title.Contains(word)))
.Select(x => new { Record = x, Order = 2 }));
data = data.Concat(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Description.Contains(word)))
.Select(x => new { Record = x, Order = 3}));
data = data.Concat(
db.LessonsLearneds
.Where(dbRecord => words.Any(word => dbRecord.Lesson.Contains(word)))
.Select(x => new { Record = x, Order = 4 }));
Then replace the Distinct with GroupBy using x.Record as a key and taking min Order for each grouping, and do the rest as in your current query:
return data
.GroupBy(x => x.Record)
.Select(g => new { Record = g.Key, Order = g.Min(x => x.Order) })
.OrderBy(x => x.Order)
.ThenByDescending(x => x.Record.Date)
.Select(x => x.Record)
.ToPagedList(pageNumber, pageSize);
You can replace Distinct with GroupBy and Select, like this:
return data
.GroupBy(x => x.Record)
.Select(g => g.OrderBy(x => x.Order).ThenByDescending(x => x.Record.Date).First())
.OrderBy(x => x.Order)
.ThenByDescending(x => x.Record.Date)
.Select(x => x.Record)
.ToPagedList(pageNumber, pageSize);
The unfortunate side effect of this approach is that you need to repeat OrderBy inside the first Select, but it should produce the results that you are looking for.
I am trying to construct a LINQ query in C# that will give me a list of distinct values from a column in a dataset with a count for each row. The results would look like this.
State Count
AL 55
AK 40
AZ 2
Here is the SQL that does that.
SELECT name, COUNT(*) AS count
FROM architecture arch
GROUP BY name
ORDER BY name
I've figured out the LINQ to get the DISTINCT values which is.
var query = ds.Tables[0].AsEnumerable()
.OrderBy(dr1 => dr1.Field<string>("state"))
.Select(dr1 => new {state = dr1.Field<string>("state")})
.Distinct().ToList();
But I can't figure out how to get the COUNT(*) for each distinct value to work in LINQ. Any idea how I can add that into the LINQ query?
You need to group your results based on State and the Select count from the group like:
var query = ds.Tables[0].AsEnumerable()
.GroupBy(r => r.Field<string>("state"))
.Select(grp => new
{
state = grp.Key,
Count = grp.Count()
})
.OrderBy(o => o.state)
.ToList();
Group all rows by value of state column. Then order groups by grouping key. And last step - project each group into anonymous object with grouping key (state) and count of rows in group:
var query = ds.Tables[0].AsEnumerable()
.GroupBy(r => r.Field<string>("state"))
.OrderBy(g => g.Key)
.Select(g => new { State = g.Key, Count = g.Count() })
.ToList();
Query syntax will look like (I'll skip converting to list, to avoid mixing syntaxes):
var query = from r in ds.Tables[0].AsEnumerable()
group r by r.Field<string>("state") into g
orderby g.Key
select new {
State = g.Key,
Count = g.Count()
};
I think you need GroupBy
var query = ds.Tables[0].AsEnumerable()
.GroupBy(dr1 => dr1.Field<string>("state"))
.Select(g => new {state = g.Key, count = g.Count())
.ToList();
Why bother with Distinct, when you can translate your SQL query to LINQ almost word-for-word? You can do it like this:
var query = ds.Tables[0].AsEnumerable()
.GroupBy(dr1 => dr1.Field<string>("state"))
.Select(g => new {
State = g.Key
, Count = g.Count()
})
.OrderBy(p => p.State)
.ToList();
This produces a list of {State, Count} pairs. If you prefer a dictionary of state-to-count, you can change your query like this:
var query = ds.Tables[0].AsEnumerable()
.GroupBy(dr1 => dr1.Field<string>("state"))
.ToDictionary(g => g.Key, g => g.Count());
var query = ds.Tables[0].AsEnumerable()
.GroupBy(x=>x.Field<string>("state"))
.Select( g => new{
state = g.Key,
count = g.Count()
});
Guess what, the equivalent of group by is group by :)
var query = from dr1 in ds.Tables[0].AsEnumerable()
group dr1 by dr1.Field<string>("state") into state
select new { State = state.Key, Count = state.Count() };
var stat = from row in ds.Tables[0].AsEnumerable()
group row by new
{
Col1 = row["Name"],
} into TotalCount
select new
{
ActionName = TotalCount.Key.Col1,
ActionCount = TotalCount.Count(),
};
I'm trying to translate this sql statement
SELECT row, SUM(value) as VarSum, AVG(value) as VarAve, COUNT(value) as TotalCount
FROM MDNumeric
WHERE collectionid = 6 and varname in ('C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19')
GROUP BY row
into an EF 4 query using lambda expressions and am missing something.
I have:
sumvars = sv.staticvararraylist.Split(',');
var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid)
.Where(r => sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row)
.Select(rg =>
new
{
Row = rg.Key,
VarSum = rg.Sum(p => p.value),
VarAve = rg.Average(p => p.value),
TotalCount = rg.Count()
});
where the staticvararraylist has the string 'C3INEV1', 'C3INEVA2', 'C3INEVA3', 'C3INVA11', 'C3INVA17', 'C3INVA19' (without single quotes) and the _collid variable = 6.
While I'm getting the correct grouping, my sum, average, & count values aren't correct.
You didn't post your error message, but I suspect it's related to Contains. I've found that Any works just as well.
This should get you quite close:
var result =
from i in _myIFR.MDNumerics
where i.collectionid == _collid && sumvars.Any(v => i.varname == v)
group i by i.row into g
select new {
row = g.Key,
VarSum = g.Sum(p => p.value),
VarAve = g.Average(p => p.value),
TotalCount = g.Count()
};
Try this:
var aavresult = _myIFR.MDNumerics
.Where(r => r.collectionid == _collid && sumvars.Contains(r.varname))
.GroupBy(r1 =>r1.row,
(key,res) => new
{
Row = key,
VarSum = res.Sum(r1 => r1.value),
VarAve = res.Average(r1 => r1.value),
TotalCount = res.Count()
});
// To get current user id
var currentUsrId = Convert.ToInt16(Membership.GetUser().ProviderUserKey);
var IDquery = My_usr_contacts_requests.Where(i => i.requests_to_usr_id == currentUsrId)
.Select(i => new { i.from_usr_id })
.ToArray();
var mainquery = My_usr_biographic_details
.Join(
My_usr_profiles_companies, i => i.usr_id, j => j.company_usr_id,
(i, j) => new
{
usr_id = j.company_usr_id,
})
.Where(i =>IDquery.contains(i.usr_id))
.ToArray();
while I am executing I am getting array of values in IDquery, and I want to use these values in the where condition of mainquery as shown above, but when I give like this it showing error at the mainquery where condition. Can you tell me how to use the array of values retrieved from IDquery in mainquery?
You wrote:
var IDquery = dbContext.My_usr_contacts_requests.Where(i =>
i.Usr_contacts_requests_to_usr_id==currentUsrId).Select(i => new {
i.Usr_contacts_requests_from_usr_id }).ToArray();
The last new is unnecessary. It creates an array of arrays. You need to change it to:
var IDquery = dbContext.My_usr_contacts_requests.Where(i =>
i.Usr_contacts_requests_to_usr_id==currentUsrId).Select(i =>
i.Usr_contacts_requests_from_usr_id).ToArray();