How to get query result if linq to DataTable? - linq

Can any one tell, how to get the result of LINQ query contains group by to DataTable .
var query= from d in dtable.AsEnumerable()
group d by d["Id"];
WId FirstName LastName Age
1 Jass we 23
1 Mady wer 54
3 Servy gr 22
4 Jan fr 11
Expected
WId FirstName LastName Age
1 Jass we 23
3 Servy gr 22
4 Jan fr 11
Thanks
Pradeep

If you just want to take the first person per ID-Group:
var distinctIdPersons = from p in dtable.AsEnumerable()
group p by p.Field<int>("WId") into IdGroups
select IdGroups.First();
or in method syntax:
distinctIdPersons = dtable.AsEnumerable().GroupBy(r => r.Field<int>("WId"))
.Select( g => g.First());
If you want to see the result(f.e. for testing purposes), you can use string.Join:
var output = string.Join(", ", distinctIdPersons.Select(r =>
r.Field<string>("FirstName") + " " + r.Field<string>("LastName")));
Console.WriteLine(output); // Jass we, Servy gr, Jan fr

Related

add AlternateKey to model in asp.net

i have one table like this
id
version
secondId
1
1
1000
1
2
1000
1
3
1000
2
1
1001
2
2
1001
2
3
1001
verion and id are composite key . i want to add auto increment secondId . for all id , secondId is same but version is diffrent. i dont konw how to handle this in code first EF .
i write blow code in dbcontext file
modelBuilder.Entity<user>().HasKey(e => new { e.Id, e.Version });
modelBuilder.Entity<user>().HasAlternateKey(q => new { q.Version, q.SecondId });
modelBuilder.Entity<user>().Property(q => q.SecondId).UseIdentityAlwaysColumn();
modelBuilder.Entity<user>().Property(q => q.SecondId).HasIdentityOptions(1000);

Why Won't This LINQ Return A Particular Initial?

I have the following LINQ:-
private static IEnumerable<AlphabetisedContact> _getGroupedContacts(int clientid)
{
return _getLiteContacts(clientid).GroupBy(c => c.Name[0]).Select(
g => new AlphabetisedContact { Initial = g.Key, Contacts = g.ToList() }).OrderBy(g => g.Initial); }
Which returns all contacts except any with the letter a? Am I missing something?
edit Currently it returns something like this:-
[{
"$id": "1",
"Initial": "B",
"Contacts": [{
"$id": "2",
"ContactId": 12,
"Name": "Bryan Chiney",
"PrimaryContact": {
"$id": "3",
"Type": "Email",
"Value": "bazrith#hotmail.com"
},
"Avatar": "/images/avatars/default.jpg",
"UserId": null
}, {
"$id": "4",
"ContactId": 22,
"Name": "Bryan Billbags",
"PrimaryContact": {
"$id": "5",
"Type": "Email",
"Value": "bryan#atomic.com"
},
"Avatar": "/images/avatars/contacts/randomiser/1.jpg",
"UserId": 15
},
...
I would expect the first Initial block to include my number of A contacts... If I add a new contact with the name Bryn McWinkawonk for instance, he'll appear, but Alice Alikemen doesn't...?
edit _getLiteContacts() call accesses the database with the passed param:-
private static IEnumerable<LiteContact> _getLiteContacts(int clientid)
{
return _getContacts(clientid).Select(c => new LiteContact()
{ ContactId = c.ContactId, ContactType = Enum.GetName(typeof (ContactTypeObject.Type), c.Type), Name = c.Name, PrimaryContact = _marshallFirstContactDetail(c.ContactId),
Avatar = c.Avatar, UserId = c.UserId }).ToList();
}
_getContacts():-
private static IEnumerable<Contact> _getContacts(int clientid)
{
using (var ctx = new atomicEntities())
{
var contacts = from c in ctx.Contacts
where c.ClientId == clientid
select c;
return contacts.ToList();
}
}
_marshallFirstContactDetail():-
private static Model.Contact.ContactDetail _marshallFirstContactDetail(int contact)
{
return _marshallContactDetails(contact).FirstOrDefault();
}
_marshallContactDetails():-
private static IEnumerable<Model.Contact.ContactDetail> _marshallContactDetails(int contact)
{
using (var ctx = new atomicEntities())
{
var o = from d in ctx.ContactDetails
join cd in ctx.ContactDetailTypes on d.ContactDetailTypeId equals cd.ContactDetailTypeId
where d.ContactId == contact
select new Model.Contact.ContactDetail {Type = cd.Description, Value = d.Description};
return o.ToList();
}
}
example data
contact_id client_id contact_name contact_type
8 22 Cain Allan 2
9 23 Bazrith Banners 2
10 22 Spencer Grep 1
12 22 Bryan Chiney 1
13 22 Dave Carter 4
15 22 Steve Tite 8
16 22 Henry Laythorpe 8
17 22 Chris Barker 8
18 22 Simon Cox 2
19 22 Russell Jacobs 1
20 22 John Wyndham 2
21 22 Isabel March 5
22 22 Bryan Billbags 2
23 22 Stu Plum 2
24 22 Pete Sorensen 7
25 22 Tom Francis 1
26 22 Rich McCormick 1
27 22 Tim Cain 4
28 22 Alex Ray-Harvey 1
29 22 Ryan Bennett 1
30 22 Alice Griswald 3
31 22 Archibald Smyth 3
32 22 Benjamin Franklin 5
Help appreciated.
OK. Firstly, a big apology to whomever took the time to look at this question. Turns out the problem was in the layer above this where some paging took place. A piece of LINQ was run on the result of the GetGroupedContacts (=> _getGroupedContacts()) like so:-
GetGroupedContacts().Take(1000).Skip(1)
This naturally, always skipped the first result.
Complete spanner dooburt signing off!

Please suggest a linq query for my requirement

Can anyone suggest a linq query for the below requirement.
There is a Checkbox on the form..when we click on it...As per the below datatable it has to be grouped according to ItemCode,Sum(SoldQty), StockInHand,LatestRecordValueOfSales, Amount, Description.
You can't group. the following columns
solddate - show the latest sold date
department
category
ItemCode Description UOM SoldQty Stock in Hand SellPrice Amount
---------------------------------------------------------------
100 Paracetamol 200MG UOM1 5 -5 3 8 0 100 1/21/2013 MEAT INDIAN BEAF
100 Paracetamol 200MG UOM1 5 -5 3 8 0 100 1/21/2013 MEAT INDIAN BEAF
200 frozen meat Kilograms 0.005 88.19 4 4.01 0 200 1/21/2013 OTHERS INDIAN BEAF
200 frozen meat Kilograms 0.044 88.19 4 4.04 0 200 1/21/2013 OTHERS INDIAN BEAF
100 Paracetamol 200MG UOM1 5 -5 3 8 0 100 1/22/2013 MEAT INDIAN BEAF
200 frozen meat Kilograms 0.054 88.19 4 4.05 0 200 1/22/2013 OTHERS INDIAN BEAF
200 frozen meat Kilograms 0.055 88.19 4 4.06 0 200 1/22/2013 OTHERS INDIAN BEAF
========================================================================
General query
var resQuery = from i in someQueryable
group i by new {i.groupProperty1, i.groupProperty2} into g
select new
{
Property1 = g.Key.Property1,
Property2 = g.Key.Property2
Total = g.Sum(p => p.SumProperty),
/// other properties
};
For your example data it could be like:
var resQuery = from i in dbContext.Items
group i by new{ i.ItemCode, i.Description, i.UOM} into g
select new
{
ItemCode = g.Key.ItemCode,
TotalSold = g.Sum(p => p.SoldQty),
Description = g.Key.Description,
UOM =g.Key.UOM
/// other properties
};
Try example on Ideone: http://ideone.com/xXwgoG
Similar questions asked on SO many times:
Linq Objects Group By & Sum
LINQ Lambda Group By with Sum
Multiple group by and Sum LINQ
Below is my code and it works fine but only for the first row the soldqty and Amount values are getting doubled.while other rows data is fine.I am not able to understand why only the first row data Sum(SoldQty) is getting doubled.
decimal? SoldQty, stockinhand,SellPrice,Amount,CostPrice;
string ItemCode, Description,UOM,BarCode,SoldDate,Department,Category,User;
var resQuery = from row in dtFilter.AsEnumerable()
group row by row.Field<string>("Item Code") into g
select dtFilter.LoadDataRow(new object[]
{
ItemCode=g.Key,
Description=g.Select(r=>r.Field<string>("Description")).First<string>(),
UOM=g.Select(r=>r.Field<string>("UOM")).First<string>(),
SoldQty = g.Sum(r => r.Field<decimal?>("Sold Qty")).Value,
stockinhand=g.Select(r=>r.Field<decimal?>("Stock in Hand")).First<decimal?>(),
SellPrice=g.Select(r=>r.Field<decimal?>("Sell Price")).First<decimal?>(),
Amount = g.Sum(r => r.Field<decimal?>("Amount")).Value,
CostPrice = g.Sum(r => r.Field<decimal?>("Cost Price")).Value,
BarCode=g.Select(r=>r.Field<string>("Barcode")).First<string>(),
SoldDate=g.Select(r=>r.Field<string>("SoldDate")).Last<string>(),
Department=g.Select(r=>r.Field<string>("Department")).First<string>(),
Category=g.Select(r=>r.Field<string>("Category")).First<string>(),
User=g.Select(r=>r.Field<string>("User")).First<string>(), }, false);

EF Linq query comparing data from multiple rows

I would like to create a Linq query that compares date from multiple rows in a single table.
The table consists of data that polls a web-services for balance data for account. Unfortunately the polling interval is not a 100% deterministic which means there can be 0-1-more entries for each account per day.
For the application i would need this data to be reformatted in a certain formatted (see below under output).
I included sample data and descriptions of the table.
Can anybody help me with a EF Linq query that will produce the required output?
table:
id The account id
balance The available credits in the account at the time of the measurement
create_date The datetime when the data was retrieved
Table name:Balances
Field: id (int)
Field: balance (bigint)
Field: create_date (datetime)
sample data:
id balance create_date
3 40 2012-04-02 07:01:00.627
1 55 2012-04-02 13:41:50.427
2 9 2012-04-02 03:41:50.727
1 40 2012-04-02 16:21:50.027
1 49 2012-04-02 16:55:50.127
1 74 2012-04-02 23:41:50.627
1 90 2012-04-02 23:44:50.427
3 3 2012-04-02 23:51:50.827
3 -10 2012-04-03 07:01:00.627
1 0 2012-04-03 13:41:50.427
2 999 2012-04-03 03:41:50.727
1 50 2012-04-03 15:21:50.027
1 49 2012-04-03 16:55:50.127
1 74 2012-04-03 23:41:50.627
2 -10 2012-04-03 07:41:50.727
1 100 2012-04-03 23:44:50.427
3 0 2012-04-03 23:51:50.827
expected output:
id The account id
date The data component which was used to produce the date in the row
balance_last_measurement The balance at the last measurement of the date
difference The difference in balance between the first- and last measurement of the date
On 2012-04-02 id 2 only has 1 measurement which sets the difference value equal to the last(and only) measurement.
id date balance_last_measurement difference
1 2012-04-02 90 35
1 2012-04-03 100 10
2 2012-04-02 9 9
2 2012-04-03 -10 -19
3 2012-04-02 3 -37
3 2012-04-03 0 37
update 2012-04-10 20:06
The answer from Raphaƫl Althaus is really good but i did make a small mistake in the original request. The difference field in the 'expected output' should be either:
the difference between the last measurement of the previous day and the last measurement of the day
if there is no previous day then first measurement of the day should be used and the last measurement
Is this possible at all? It seems to be quite complex?
I would try something like that.
var query = db.Balances
.OrderBy(m => m.Id)
.ThenBy(m => m.CreationDate)
.GroupBy(m => new
{
id = m.Id,
year = SqlFunctions.DatePart("mm", m.CreationDate),
month = SqlFunctions.DatePart("dd", m.CreationDate),
day = SqlFunctions.DatePart("yyyy", m.CreationDate)
}).ToList()//enumerate there, this is what we need from db
.Select(g => new
{
id = g.Key.id,
date = new DateTime(g.Key.year, g.Key.month, g.Key.day),
last_balance = g.Select(m => m.BalanceValue).LastOrDefault(),
difference = (g.Count() == 1 ? g.First().BalanceValue : g.Last().BalanceValue - g.First().BalanceValue)
});
Well, a probable not optimized solution, but just see if it seems to work.
First, we create a result class
public class BalanceResult
{
public int Id { get; set; }
public DateTime CreationDate { get; set; }
public IList<int> BalanceResults { get; set; }
public int Difference { get; set; }
public int LastBalanecResultOfDay {get { return BalanceResults.Last(); }}
public bool HasManyResults {get { return BalanceResults != null && BalanceResults.Count > 1; }}
public int DailyDifference { get { return HasManyResults ? BalanceResults.Last() - BalanceResults.First() : BalanceResults.First(); } }
}
then we change a little bit our query
var query = db.Balances
.GroupBy(m => new
{
id = m.Id,
year = SqlFunctions.DatePart("mm", m.CreationDate),
month = SqlFunctions.DatePart("dd", m.CreationDate),
day = SqlFunctions.DatePart("yyyy", m.CreationDate)
}).ToList()//enumerate there, this is what we need from db
.Select(g => new BalanceResult
{
Id = g.Key.id,
CreationDate = new DateTime(g.Key.year, g.Key.month, g.Key.day),
BalanceResults = g.OrderBy(l => l.CreationDate).Select(l => l.BalanceValue).ToList()
}).ToList();
and finally
foreach (var balanceResult in balanceResults.ToList())
{
var previousDayBalanceResult = balanceResults.FirstOrDefault(m => m.Id == balanceResult.Id && m.CreationDate == balanceResult.CreationDate.AddDays(-1));
balanceResult.Difference = previousDayBalanceResult != null ? balanceResult.LastBalanecResultOfDay - previousDayBalanceResult.LastBalanecResultOfDay : balanceResult.DailyDifference;
}
as indicated, performance (use of dictionaries, for example), code readability should of course be improved, but... that's the idea !

Method to get a summary view from a dataset

I have a dataset that looks like this:
Date
Category
Rate
Quantity
There will be 0 or 1 row for each Category for any given Date.
What is a good way to get this data into a summary type of view?
For example:
Date
Category1_Rate
Category2_Rate
Category3_Rate
Category4_Rate
I have a fixed number of Categories.
I'm using linq.
Here is an example. If I have this data:
Date Category Rate Quantity
1/1/12 toys 15 12
1/1/12 games 20 20
1/1/12 dvds 18 30
1/2/12 toys 19 13
1/2/12 dvds 20 17
I want to produce a summary that looks like this:
Date toys_rate games_rate dvds_rate
1/1/12 15 20 18
1/2/12 19 null 20
Possibly something like this
var summarydata =
from r in table
group r by r.Date into g
select new
{
Date = g.Key,
ToysRate = g.Where(e=> e.Category == "toys").Count() > 0 ?
(int?)g.Where(e=> e.Category == "toys").First().Rate : null,
GamesRate = g.Where(e=> e.Category == "games").Count() > 0 ?
(int?)g.Where(e=> e.Category == "games").First().Rate : null,
DvdsRate = g.Where(e=> e.Category == "dvds").Count() > 0 ?
(int?)g.Where(e=> e.Category == "dvds").First().Rate : null
};
Note I haven't tested this as I don't current have access to a C# environment.
EDIT - Added nullable int casts to properly set the type of the various rate fields in the resulting anonymous type.

Resources