Get All Entities From EntityCollection Where Values Matches X - linq

I would like to get all matched Entities from an EntityCollection by a value, but my current statement only allow return of Entity, and not EntityCollection.
//only allow return 1 entity
var matchedRecords = allRecords.Entities.Where
(x => x.GetAttributeValue<EntityReference>
("ccc_batchId").Id == batchId);
May I know how can I tweak the above query?

EntityCollection is just a construct to store more than one Entity.
I know it's not ideal but you can always convert the allRecords.Entities inside a List of Entity and do your LINQ query against it.
Your code is probably returning an IEnumerable of Entity and not a single Entity (for example in the end of your query you can put a .ToList() to get a List of Entity.

Building on what Guido said, it is also possible to create a new EntityCollection with the results:
var matchedRecords = allRecords.Entities.Where(x => x.GetAttributeValue<EntityReference>("ccc_batchId").Id == batchId).ToList();
var matchedCollection = new EntityCollection(matchedRecords);

Related

Dynamic Linq on DataTable error: no Field or Property in DataRow, c#

I have some errors using Linq on DataTable and I couldn't figure it out how to solve it. I have to admit that i am pretty new to Linq and I searched the forum and Internet and couldn't figure it out. hope you can help.
I have a DataTable called campaign with three columns: ID (int), Product (string), Channel (string). The DataTable is already filled with data. I am trying to select a subset of the campaign records which satisfied the conditions selected by the end user. For example, the user want to list only if the Product is either 'EWH' or 'HEC'. The selection criteria is dynaically determined by the end user.
I have the following C# code:
private void btnClick()
{
IEnumerable<DataRow> query =
from zz in campaign.AsEnumerable()
orderby zz.Field<string>("ID")
select zz;
string whereClause = "zz.Field<string>(\"Product\") in ('EWH','HEC')";
query = query.Where(whereClause);
DataTable sublist = query.CopyToDataTable<DataRow>();
}
But it gives me an error on line: query = query.Where(whereClause), saying
No property or field 'zz' exists in type 'DataRow'".
If I changed to:
string whereClause = "Product in ('EWH','HEC')"; it will say:
No property or field 'Product' exists in type 'DataRow'
Can anyone help me on how to solve this problem? I feel it could be a pretty simple syntax change, but I just don't know at this time.
First, this line has an error
orderby zz.Field<string>("ID")
because as you said, your ID column is of type int.
Second, you need to learn LINQ query syntax. Forget about strings, the same way you used from, orderby, select in the query, you can also use where and many other operators. Also you'll need to learn the equivalent LINQ constructs for SQL-ish things, like for instance IN (...) is mapped to Enumerable.Contains etc.
With all that being said, here is your query
var productFilter = new[] { "EWH", "HEC" };
var query =
from zz in campaign.AsEnumerable()
where productFilter.Contains(zz.Field<string>("Product"))
orderby zz.Field<int>("ID")
select zz;
Update As per your comment, if you want to make this dynamic, then you need to switch to lambda syntax. Multiple and criteria can be composed by chaining multiple Where clauses like this
List<string> productFilter = ...; // coming from outside
List<string> channelFilter = ...; // coming from outside
var query = campaign.AsEnumerable();
// Apply filters if needed
if (productFilter != null && productFilter.Count > 0)
query = query.Where(zz => productFilter.Contains(zz.Field<string>("Product")));
if (channelFilter != null && channelFilter.Count > 0)
query = query.Where(zz => channelFilter.Contains(zz.Field<string>("Channel")));
// Once finished with filtering, do the ordering
query = query.OrderBy(zz => zz.Field<int>("ID"));

preserving the order of returning entities when using .Contains(Id)

I want to hydrate a collection of entities by passing in a List of Ids and also preserve the order.
Another SO answer https://stackoverflow.com/a/15187081/1059911 suggested this approach to hydrating the entities which works great
var entities = db.MyEntities.Where(e => myListOfIds.Contains(e.ID)).ToList();
however the order of entities in the collection is different from the order of Ids
Is there a way to preserve the order?
May be that helps:
var entities = db.MyEntities
.Where(e => myListOfIds.Contains(e.ID))
.OrderBy(e => myListOfIds.IndexOf(e.ID)).ToList();
EDIT
JohnnyHK clarified that this will not work with LINQ to Entities. For this to work you need to order IEnumerable instead of IQueryable, since IQueryProvider don't know how to deal with local list IndexOf method when it sends query to server. But after AsEnumerable() OrderBy method deals with local data. So you can do this:
var entities = db.MyEntities
.Where(e => myListOfIds.Contains(e.ID))
.AsEnumerable()
.OrderBy(e => myListOfIds.IndexOf(e.ID)).ToList();
Entity Framework contains a subset of all of the LINQ commands so you won't have all the commands that LINQ to Objects has.
The following approach should give you your list of MyEntities in the same order as supplied by myListOfIds:
var entities = myListOfIds.Join(db.MyEntities, m => m, e => e.ID, (m,e) => e)
.ToList();

Return Linq query results into List object

I am trying to return the results of a query into a List object, however the following code, as I normally use, does not work. Still relatively new to Linq, can someone explain the correct syntax/what's going on? This will work if I change the data type of productTraining to var...
List<AgentProductTraining> productTraining = new List<AgentProductTraining>();
productTraining = from records in db.CourseToProduct
where records.CourseCode == course.CourseCode
select records;
Select() and Where() will return IQueryable<T>, not List<T>. You've got to convert it to a List<T> - which actually executes the query (instead of just preparing it).
You just need to call ToList() at the end of the query. For example:
// There's no need to declare the variable separately...
List<AgentProductTraining> productTraining = (from records in db.CourseToProduct
where records.CourseCode == course.CourseCode
select records).ToList();
Personally I wouldn't use a query expression though, when all you're doing is a single Where clause:
// Changed to var just for convenience - the type is still List<AgentProductTraining>
var productTraining = db.CourseToProduct
.Where(records => records.CourseCode == course.CourseCode)
.ToList();

Convert IQueryable to List<T> type

I just performed a query with LINQ from the DAL and got a collection of a record with imbedded ILIST objects like the following
string name
date startDate
date endDate
ILIST<MyType> ImbeddedList (this contains more columns like recordID, sentDate, dueDate)
I need to return a LIST<T> back to the grid to be bounded.
I am having some problems with writing the LINQ statement to filter out the IQueryable collection object.
In my statement below:
IQueryable<All_DATA> cases = dalObject.GetData();
var mylist = cases.Select(s => {s.name, s.startDate, s.endDate,s.ImbeddedList????}).ToList();
When I get to the ImbeddedList, which is returned from the dalObject, the intellsense does not show the fields in the ImbeddedList. How can I correctly write the LINQ statement to filter for more fields in the ImbeddedList object?
As far I understand what you can do is
For fetching complete list from ImbeddedList
var mylist = cases.Select(s => {s.name, s.startDate, s.endDate, s.ImbeddedList}).ToList();
And for fetching individual field from ImbeddedList
var mylist = cases.SelectMany(s => s.ImbeddedList)
.Select(IItem => { IItem.Field1, IItem.Field2 }).ToList();
For more information please refer:
The Linq SelectMany Operator
LINQ - Get all items in a List within a List?
Using LINQ, select list of objects inside another list of objects
Use Google Search: "linq select list within list"

How to return distinct rows from and Entity with related Entities

I have an Entity that has an association to other Entities (related entities). I'm trying to return distinct rows from the primary entity which needs to include the data from the related entity so I can use one the related entity's properties downstream.
Below is the statement I'm using but it is not returning any rows. What's the best way to do this?
Below is my code.
return context.UserDisplays.Include("CurrentJob").Where(d => d.UserName == userName).GroupBy(d => d.CurrentJob.JobNo).Select(g => g.FirstOrDefault()).ToList();
Any help would be greatly appreciated!
Edit - For ComplexProperty
I believe once you do a GroupBy all Include methods are ignored. So you will need to iterate the list and call the LoadProperty method on each item. It should look something like this
var list = context.UserDisplays
.Where(d => d.UserName == userName)
.GroupBy(d => d.CurrentJob.JobNo)
.Select(g => g.FirstOrDefault()).ToList();
foreach(var item in list)
{
context.LoadProperty(item, "CurrentJob");
}
return list;
Resource Link
Check out the Distinct (Set Operators) section in this article
http://msdn.microsoft.com/en-us/vcsharp/aa336746
Are you asking for the Distinct UserDisplays? or the Distinct User or the Disticnt Jobs?
I would try say something like
var object = (from userDisplay in context.UserDisplays.Include("CurrentJob")
.Where userDisplay.UserName == userName
Select userDisplay).Distinct();
(sorry, im going off of my VB style but it should be about the same...)

Resources