WhereSelectEnumerableIterator to data table c# - c#

I have linq query that I don't know to how get values from cells
for instance how I get sum of totalt for specific group
or how can I convert result to a datatable?
thanks in advance
var result = from tab in dtLines.AsEnumerable()
group tab by tab["GoodsRef"]
into groupDt
select new
{
Group = groupDt.Key,
PriceP = groupDt.Sum((r) => decimal.Parse(r["PriceP"].ToString())),
TotalT = groupDt.Sum((r) => decimal.Parse(r["TotalT"].ToString()))
};

You can retrieve whatever you like from result just like this:
// TotalT for a group: GoodsRef == "Electrical Goods"
var x = result.FirstOrDefault(t => t.Group == "Electrical Goods").TotalT;
// Some of all TotalT
var totalSum = result.Sum(t => t.TotalT);

Related

C#- LINQ Grouping on a custom created date range

So, I have this LINQ query:
var Result = from u in Users
group u by new {u.AccountType, u.Id,u.CreationDate} into usergroup
select new {id=usergroup.Key.Id,CreationDate=usergroup.Key.CreationDate,AccountType=usergroup.Key.AccountType};
that returns the following data set:
I am able to get the individual group count like this:
var myresult=Result.GroupBy(n=>n.AccountType).Select(n=>new {AccountType=n.Key,TotalCount=n.Count()});
which gives me:
Now suppose, I define a custom date range of Months from January-December, how can I do a group on the first data-set to give me count of AccountType based on each month based on the CreationDate column into my custom date range?
I am trying to understand what type you would like your result to be in. If you want a list of Months, each of which would have a tally of Accounts per AccountType, then you could try something like this:
var myResult2 = result.GroupBy(o => o.CreationDate.Month).Select(monthGroup => new
{
Month = System.Globalization.DateTimeFormatInfo.CurrentInfo.GetMonthName(monthGroup.Key),
Accounts = monthGroup.GroupBy(o => o.AccountType).ToDictionary(accountGroup => accountGroup.Key, accountGroup => accountGroup.Count())
});
Try this:
I think this will do your job
.GroupBy(g => new { g.CreationDate.Date.Month, g.AccountType })
.Select(t => new { t.Key.AccountType, t.Key.Month, Count = t.Count() });
If CreationDate is a string:
var group = result.GroupBy(g => new { DateTime.Parse(g.CreationDate).Date.Month, g.AccountType })
.Select(user => new { user.Key.AccountType, user.Key.Month, Count = user.Count() });
foreach (var g in group)
{
Console.WriteLine($"Users with Month[{g.Month}] : {g.Count}, AccType: {g.AccountType};");
}
I Have Try Below Code:
var data = Users.GroupBy(x => new {x.column1 , x.column2 ,...})
.Select(y=> new className() { column1 = y.Key.column1 , column2 = y.Key.column2}).ToList<className>();

display two table data at a time in linq

I want to to display two tables information at a time.
List<int> order_track = db.Order_Trackings.Where(e => e.UID == id).Select(q => q.ID).ToList();
if (order_track == null)
{
var rate = db.Ratings.OrderByDescending(e => e.Rate).Take(5);
}
List<int> fidList = db.OrderFoods.Where(q => order_track.Contains(q.OID)).Select(q => q.FID).ToList();
var qs = (from x in fidList
group x by x into g
let count = g.Count()
orderby count descending
select new { KEY = g.Key });
if (order_track.Count == 2)
{
var one = qs;
List<int> idList = new List<int>();
foreach (var val in one)
{
idList.Add(val.KEY);
}
var food = db.Foods.Where(q => idList.Contains(q.ID));
var rate = db.Ratings.OrderByDescending(e => e.Rate).FirstorDefault();
return Request.CreateResponse(HttpStatusCode.OK, rate);
I want to do something like this I hope you will understand what i am trying to achieve Thanks in advance.
var food = db.Foods.Where(q => idList.Contains(q.ID)&&db.Ratings.OrderByDescending(e => e.Rate).FirstorDefault());
return Request.CreateResponse(HttpStatusCode.OK, rate);
If you want to combine the two results into one variable, then the easiest way to do so is by creating an anonymous object, like this:
var result = new
{
food = db.Foods.Where(q => idList.Contains(q.ID)),
rate = db.Ratings.OrderByDescending(e => e.Rate).FirstorDefault()
};
return Request.CreateResponse(HttpStatusCode.OK, result);
You could also create a class with two properties and then create an instance of that class, but if this is the only place where you would use that class then I wouldn't bother doing that.

Filter and add values using C# using lambda expression

New to C# and appreciate any help. The issue is that I need to filter the results of my api call against an array (using an "allowedA" and "allowedB" array.) I don't know how to edit the lambda expression to check against the loop.
var activities = await _restClientTaxonomy.GetTaxonomyFullAsync(TAXONOMY_CLASSIFICATIONID_FOR_ACTIVITY);
var activityTypes = await _restClientTaxonomy.GetTaxonomyFullAsync(TAXONOMY_CLASSIFICATIONID_FOR_ACTIVITY_TYPES);
var documentEventxx = activities.Select(type => type.Id);
long [] allowedA = new long []{ 7137, 40385637};
long [] allowedB = new long []{ 7137, 40385637};
foreach (long value in documentEventxx)
{
foreach (var item in allowed)
{
if (item == value) {
//These are the values I am looking for -> values that are part of the documentEventxx and allowedB.
}
}
}
var result = activityTypes.Select(type => new CategoryViewModel
{
Id = type.Id,//This is where I want to add only items that are in the allowedA array
Text = type.Name,
Types = activities.Where(a => a.ParentId == type.Id).Select(t => new TaxonomyMemberTextItem
{
Id = t.Id, //This is where I want to add only items that are in the allowedB array
Text = t.Name
}).ToList()
}).ToArray();
I have been reading about lambda expressions and foreach loops so please don't just post a random link.
Thanks in advance.
Filter the values before Selecting.
activityTypes.Where(x=>allowedA.Contains(x.Id)).Select(type => new CategoryViewModel
{
Id = type.Id,
Text = type.Name,
Types = activities.Where(a => a.ParentId == type.Id && allowedB.Contains(a.Id)).Select(t => new TaxonomyMemberTextItem
{
Id = t.Id,
Text = t.Name
}).ToList()
})
To filter you use .Where. You .Select to create a list of new types. So in order to filter, then create the lists of objects you want:
var result = activityTypes.Where(type=>isAllowed(type.Id)).Select(type => new CategoryViewModel
{
Id = type.Id,//This is where I want to add only items that are in the allowedA array
Text = type.Name,
Types = activities.Where(a => a.ParentId == type.Id&&isAllowed(a.Id)).Select(t => new TaxonomyMemberTextItem
{
Id = t.Id, //This is where I want to add only items that are in the allowedB array
Text = t.Name
}).ToList()
}).ToArray();

C# lambda-> All rows Select Add Row_Number

I have a table:
DataTable store_temp = new DataTable();
store_temp.Columns.Add("patn");
store_temp.Columns.Add("rf");
store_temp.Columns.Add("name");
store_temp.Columns.Add("conv");
store_temp.Columns.Add("conv_type");
store_temp.Columns.Add("recorddate");
store_temp.Columns.Add("executiondate");
My C# code :
int i = 0;
var rowsgroups = (from row in store_temp.AsEnumerable().GroupBy(row =>
row.Field<string>("patn"))
.OrderBy((g => g.OrderByDescending(y => y.Field<string("executiondate")).ThenByDescending(y =>
y.Field<string>("rf"))))
select new
{
patn = row.ElementAt(i),
rf_num = ++i,
}).ToArray();
I want the lambda experession, which is equivalent to:
select patn, rf,
> row_number() over( partition by patn order by executiondate,rf )
as rf_num,
name, conv,conv_type, recorddate, executiondate
from store_temp2
But, lambda syntax ... var rowsgroups has just a one row..
I want to show all rows in store_temp.
What should I do to fix the query?
row_number() over(partition by patn order by executiondate, rf)
means in LINQ you need to group by patn, then order each group by executiondate, rf, then use the indexed Select overload to get row numbering inside the group, and finally flatten the result with SelectMany.
With that being said, the equivalent LINQ query could be something like this:
var result = store_temp.AsEnumerable()
.GroupBy(e => e.Field<string>("patn"), (key, elements) => elements
.OrderBy(e => e.Field<string>("executiondate"))
.ThenBy(e => e.Field<string>("rf"))
.Select((e, i) => new
{
patn = key,
rf = e.Field<string>("rf"),
rf_num = i + 1,
name = e.Field<string>("name"),
conv = e.Field<string>("conv"),
conv_type = e.Field<string>("conv_type"),
recorddate = e.Field<string>("recorddate"),
executiondate = e.Field<string>("executiondate")
}))
.SelectMany(elements => elements)
.ToArray();
Try something like this
select new
{
rowNum = store_temp.Rows.IndexOf(row),
patn = row.ElementAt(i),
rf_num = ++i,
}).ToArray();
I don't think you required any groupby as per your required sql
var i=0;
var rowsgroups = (from row in store_temp.AsEnumerable()
orderby row.Field<string>("executiondate") descending,
row.Field<string>("rf") descending
select new
{
patn = row.Field<string>("patn"),
rf_num = ++i,
name = row.Field<string>("name"),
conv = row.Field<string>("conv"),
conv_type = row.Field<string>("conv_type"),
recorddate = row.Field<string>("recorddate"),
executiondate = row.Field<string>("executiondate")
}).ToArray();

Filtering this Linq query

I want to use this query:
var queryData = from va in xdoc.Descendants("language")
select new
{
StringID = va.Parent.Parent.Attribute("id").Value,
Language = va.Attribute("name").Value,
LanguageData = va.Element("value").Value,
};
var organizedData = from x in queryData
group x by x.StringID into xg
select new
{
StringID = xg.Key,
English = xg.SingleOrDefault(x => x.Language == "ENGLISH_US").LanguageData,
Custom = xg.SingleOrDefault(x => x.Language == languageBox.SelectedItem.ToString()).LanguageData,
};
mainView.DataSource = organizedData.ToList();
mainView.Refresh();
except that as an additional condition for what is retrieved for the Custom anonymous type, its value must be equal to "*".
Why can't I figure this out? I guess I don't know enough about anonymous types or the => operator.
Is that what you want?
mainView.DataSource = organizedData.Where(x => x.Custom == "*").ToList();
I think this is what you're looking for. I put the value in a temp variable so it doesn't have to be computed twice.
var organizedData = from x in queryData
group x by x.StringID into xg
let temp = xg.SingleOrDefault(x => x.Language == languageBox.SelectedItem.ToString()).LanguageData
where temp == "*"
select new
{
StringID = xg.Key,
English = xg.SingleOrDefault(x => x.Language == "ENGLISH_US").LanguageData,
Custom = temp,
};

Categories