LINQ query to dictionary - c#

I'm trying to convert below LINQ query result into dictionary
var browser = (from tbf in context.tblFeedBacks
where tbf.email == dboard.userEmail
select tbf).GroupBy(l => l.browser)
.Select(g => new
{
browser = g.Key,
count = g.Select(l => l.browser).Distinct().Count()
});
It gives me a compilation error.
var browser = (from tbf in context.tblFeedBacks
where tbf.email == dboard.userEmail
select tbf).GroupBy(l => l.browser)
.Select(g => new
{
browser = g.Key,
count = g.Select(l => l.browser).Distinct().Count()
}).ToDictionary<string, double>(x => x.browser,y=>y.count);
Instance argument: cannot convert from
'System.Linq.IQueryable' to
'System.Linq.ParallelQuery'

got it working.
var browser = (from tbf in context.tblFeedBacks
where tbf.email == dboard.userEmail
select tbf).GroupBy(l => l.browser)
.Select(g => new
{
browser = g.Key,
count = g.Select(l => l.browser).Count()
}).ToDictionary(x => x.browser, x => x.count);

Related

C# Linq Lambda for group by multiple columns select max

I want to translate this into lambda syntax and can't seem to get it to work:
Grouping by two columns, select max on a different column, return list of complete complex object.
I am writing more text here to get past the validation on this form. How much text is needed until I am allowed to post this?
_clientpolicies = (from policy in
_reply.CommercialInsuredGroupWithPolicyTerm.InsuredWithPolicyTerm.SelectMany(x => x.PolicyTerm)
.Where(x => !(string.IsNullOrWhiteSpace(x.PolicyNumber) && string.IsNullOrWhiteSpace(x.ControlNumber)))
.Where(x => x.Insured.DNBAccountNumber == _client.LookupID)
group policy by
new
{
PolicyReference = GetPolicyReference(policy),
PolicyType = policy.ProductInformation.PolicyTypeCode
}
into g
let maxPolicyInception = g.Max(p => p.InceptionDate)
from policyGroup in g
where policyGroup.InceptionDate == maxPolicyInception
select policyGroup).ToList();
I dont think there's a way of doing it in one line. So there's my try :
policyGroups=
_reply.CommercialInsuredGroupWithPolicyTerm.InsuredWithPolicyTerm
.SelectMany(x => x.PolicyTerm)
.Where(x => !(string.IsNullOrWhiteSpace(x.PolicyNumber) && string.IsNullOrWhiteSpace(x.ControlNumber)))
.Where(x => x.Insured.DNBAccountNumber == _client.LookupID)
.GroupBy(x => GetPolicyReference(x))
.ThenBy(x => x.ProductInformation.PolicyTypeCode)
.ToList();
var maxPolicyInception = policyGroups.Max(p => p.InceptionDate);
_clientpolicies = policyGroups
.Where(g => g.InceptionDate == maxPolicyInception)
.ToList();
_clientpolicies =
_reply.CommercialInsuredGroupWithPolicyTerm.InsuredWithPolicyTerm.SelectMany(x => x.PolicyTerm)
.Where(x => !(string.IsNullOrWhiteSpace(x.PolicyNumber) && string.IsNullOrWhiteSpace(x.ControlNumber)))
.Where(x => x.Insured.DNBAccountNumber == _client.LookupID)
.GroupBy(x =>
new
{
PolicyReference = GetPolicyReference(x),
PolicyType = x.ProductInformation.PolicyTypeCode
},
(key, g) => g.OrderByDescending(gx => gx.InceptionDate).First()

Simplifying a Linq query by using Include instead of Join

I've been asked to simplify the following Linq query:
var orders = db.Orders
.Join(db.Shipments,
o => o.OrderID,
s => s.OrderID,
(o, s) => new { Order = o, Shipment = s })
.Join(db.LineItems,
s => s.Shipment.ShipmentID,
l => l.ShipmentID,
(s, l) => new { Order = s.Order, Shipment = s.Shipment, LineItem = l })
.Join(db.StatusTypes,
s => s.Shipment.StatusTypeID,
st => st.StatusTypeID,
(s, st) => new { Order = s.Order, Shipment = s.Shipment, LineItem = s.LineItem, Description = st.ExternalDescription })
.Where(x => x.Order.AccountID == accountId)
.GroupBy(x => x.Order.OrderNumber)
.ToList()
.Select(
x => new OrderStatusViewModel
{
Date = x.Max(y => y.Order.Created),
OrderNumber = x.Key,
Cost = x.Sum(y => y.LineItem.UnitPrice).ToString(),
Status = x.Max(y => y.Description)
}
);
By replacing the Joins with Includes. I've searched around, and I've discovered that Joins and Includes are somewhat equivalent. But I can't figure out how to convert this query to one that uses includes instead of joins. Is it actually less code and simpler to use includes instead of joins here?
I strongly suggest you to use navigation properties instead of manual builded joins. It will be more efficent and controlable. Read this article.
If you would convert your query to navigation property form by using Include, it would seem like that;
var orders = db.Orders
.Include(x => x.Shipments)
.Include(x => x.Shipments.Select(y => y.LineItems))
.Include(x => x.Shipments.Select(y => y.StatusType))
.Where(x => x.Order.AccountID == accountId)
.GroupBy(x => x.Order.OrderNumber)
.ToList()
.Select(
x => new OrderStatusViewModel
{
Date = x.Max(y => y.Created),
OrderNumber = x.Key,
Cost = x.LineItems.Sum(k => k.UnitPrice),
Status = x.Max(y => y.Description)
}
);
But, as I said, you should define the navigation properties for entities first.
var orders = db.Orders
.Include("Shipments")
.Include("Shipments.LineItems")
.Include("Shipments.StatusTypes")
.Where(x => x.Order.AccountID == accountId)
.GroupBy(x => x.Order.OrderNumber)
.ToList()
.Select(
x => new OrderStatusViewModel
{
Date = x.Max(y => y.Order.Created),
OrderNumber = x.Key,
Cost = x.Sum(y => y.LineItem.UnitPrice).ToString(),
Status = x.Max(y => y.Description)
}
);
i not tested above code ,just try
ObjectQuery.Include Method (String)

Linq to find lasted record in group

I want add a new column to find which is lasted record in group.
Can I write subquery in Select() method?
I have try this
var test = DailyPeriods.Where(x => x.BookingDate == "2016/12/30")
.Select(x =>
new
{
PERIOD_GROUP_ID = x.PeriodGroupID,
PERIOD_NAME = x.PeriodName,
New_Column = DailyPeriods
.Where(z => z.BookingDate == "2016/12/30")
.Select(a =>
new
{
PeriodGroupID = a.PeriodGroupID,
period_name = a.PeriodName
}
)
.GroupBy(b => b.period_name)
.Select(g => g.Last().PeriodGroupID)
.Contains(x.PeriodName)
})
But will occur this error
"column not in scope: A:2211708.C(BOOKING_DATE)"
Try this..
var lastRecords = periodList.GroupBy(l => l.PeriodName)
.Select(x => new { PeriodName = x.Key,
PeriodGroupId = x.OrderBy(l => l.PeriodGroupId).Last().PeriodGroupId});
var result = from period in periodList
from lastRec in lastRecords.Where(r => r.PeriodGroupId == period.PeriodGroupId
&& r.PeriodName == period.PeriodName)
.DefaultIfEmpty()
select new { period.PeriodGroupId,period.PeriodName, New_Column=lastRec==null?false:true };

Grouping earliest entry for each day using Linq

Trying to get my head around Linq, and at the same time keep track of the time I log on in the morning, which should be the time I get into the office thereabouts.
My code so far is:
EventLog SecurityLog = new EventLog("Security");
var AccountLoggedOnEntries = SecurityLog.Entries.Cast<EventLogEntry>()
.Where(x => x.InstanceId == 4624)
.Select(x => new
{
DateGenerated = x.TimeGenerated.ToShortDateString()
,
TimeGenerated = x.TimeGenerated.ToShortTimeString()
,
x.Message
})
.ToList();
DgvLogSummary.DataSource = AccountLoggedOnEntries;
DgvLogSummary.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
I want to filter the results so that I only have one entry for each day, which is the earliest time.
In SQL I would normally take the Message of the earliest entry and then group by all fields.
How do I perform a similar query in Linq?
In LINQ you would group by, sort each group, and pick the first item:
var AccountLoggedOnEntries = log.Entries.Cast<EventLogEntry>()
.Where(x => x.InstanceId == 4624)
.GroupBy(x => x.TimeGenerated.Date)
.Select(g => g.OrderBy(x => x.TimeGenerated).First())
.Select(x => new {
DateGenerated = x.TimeGenerated.ToShortDateString()
, TimeGenerated = x.TimeGenerated.ToShortTimeString()
, x.Message
})
.ToList();
You could GroupBy the date and then select the minimum time
var AccountLoggedOnEntries = log.Entries.Cast<EventLogEntry>()
.Where(x => x.InstanceId == 4624)
.GroupBy(x => x.TimeGenerated.Date)
.Select(x => new {
DateGenerated = x.Key
, TimeGenerated = x.Min(y => y.TimeGenerated).ToShortTimeString()
})
.ToList();
Getting the appropriate Message is a little more tricky. One easy option is to use x.First().Message in the above Select projection.
Try this :
var AccountLoggedOnEntries = log.Entries.Cast<EventLogEntry>()
.Where(x => x.InstanceId == 4624)
.GroupBy(x => x.TimeGenerated.Date)
.Select(days => days.OrderBy(time => time.TimeGenerated).FirstOrDefault())
.Select(x => new
{
DateGenerated = x.TimeGenerated.ToShortDateString()
,
TimeGenerated = x.TimeGenerated.ToShortTimeString()
,
x.Message
})
.ToList();

Comparing two lists from different tables with EntityFramework

I want to compare two lists extracted from two different tables
var maListe = db.exclure.Where(w => w.type.Contains("Object class"))
.GroupBy(g => new {libelle = g.libelle,})
.Select(s => new {libellex = s.Key.libelle}).ToList();
var myList = db.Full.Where(c => c.date_reception > new DateTime(2015, 02, 02))
.Where (c => !maListe.Any(c2 => c2.libellex.Contains(c.mc_object_class)))
//.Where (p => p.mc_object_class.CompareTo("NULL")<0)
.GroupBy(f => new
{
object_class = f.mc_object_class,
})
.Select(g => new
{
object_classx = g.Key.object_class,
countx = g.Count()
})
.Take(10)
.OrderByDescending(o => o.countx)
.ToList();
I'm looking for elements that exist in myList and not in maListe, while running the code above I get the following error:
Unable to create a constant value of type 'Anonymous type'. Only
primitive types or enumeration types are supported in this context.'
You should materialize your collection, something like:
var maListe = db.exclure.Where(w => w.type.Contains("Object class"))
.GroupBy(g => new {libelle = g.libelle,})
.Select(s => new {libellex = s.Key.libelle}).ToList();
var myList = db.Full.Where(c => c.date_reception > new DateTime(2015, 02, 02))
.AsEnumerable() // database query ends here
.Where (c => !maListe.Any(c2 => c2.libellex.Contains(c.mc_object_class)))
//.Where (p => p.mc_object_class.CompareTo("NULL")<0)
.GroupBy(f => new
{
object_class = f.mc_object_class,
})
.Select(g => new
{
object_classx = g.Key.object_class,
countx = g.Count()
})
.Take(10)
.OrderByDescending(o => o.countx)
.ToList();
If you will have time, please, take a look to msdn

Categories

Resources