Filter list having two Tables join data in Entity Framework - linq

I have two tables..
Student (StudentId,Name,FatherName)
Qualification (QualificationId,StudentId,DegreeName)
I have got data like this..
var myList = (from c in entities.Students
join q in entities.Qualifications on c.StudentId equals q.StudentId
select new {c.Name,c.FatherName,q.DegreeName}).ToList();
Now i want to filter myList more.. How can i do it, like..
var filteredList = myList.Select(c=> new Student
{
Name=c.Name,
FatherName=c.FatherName
//Degree=C.Degree
}).ToList();
The above Linq Query is not working if i want to get DegreeName also, My Question is how to further Filter myList.
Thanks.

var filteredList = myList.Where(i => i.FatherName == "Shahid").ToList();
Keep in mind since you called ToList() on the original query you are now filtering in memory. If you want to filter in the database then remove the ToList() on the first query and do it like this:
var myList = from c in entities.Students
join q in entities.Qualifications on c.StudentId equals q.StudentId
select new {
c.Name,
c.FatherName,
q.DegreeName
};
var filteredInDatabase = myList.Where(i => i.FatherName == "Shahid").ToList();

Related

How to execute a linq query for each item in a list , use it in the where clause and return a collection from the result of each query?

As you can see I'm executing the query for the first element in the list.
I would like to execute the query for each category in the list and to return one collection with the result of all queries without duplicates (A question can be in multiple categories).
public ObservableCollection<Question> GetQuestionsByCategory(List<Category> categories)
{
var c = categories[0];
var questions = from q in this.Questions where q.Categories.Contains(c)
select q;
return new ObservableCollection<Question>(questions);
}
You could do this:
var questions =
(from c in categories
from q in this.Questions where q.Categories.Contains(c)
select q).Distinct();
But I'd suggest this instead:
var questions = from q in this.Questions
where q.Categories.Any(c => categories.Contains(c))
select q;

LINQ Query To Return Duplicates Exclusively

I'm working on this LINQ query. I'd like the resulting list return a list of records that contain duplicates exclusively, based on the EMailAddress1 field and grouped by the EMailAddress1 field.
For instance:
emailaddress1#gmail.com
emailaddress1#gmail.com
emailaddress2#gmail.com
emailaddress2#gmail.com
emailaddress2#gmail.com
emailaddress3#gmail.com
emailaddress3#gmail.com
etc.
Any advice on this? Thanks.
var contacts = (from c in xrm.ContactSet
where c.StateCode != 1
orderby c.EMailAddress1, c.CreatedOn
descending select new {
c.FirstName,
c.LastName,
c.EMailAddress1,
c.ContactId,
c.CreatedOn }).ToList();
Based on your previous query:
var duplicatedEmails = (from c in contacts
group c by c.EMailAddress1 into g
where g.Count() > 1
select g.Key).ToList();
var duplicatedContacts = contacts.Where(c => duplicatedEmails.Contains(c.EMailAddress1));

Linq query select count into same entity

I got two tables: comments and commentLikes
in the same query i count the likes users have given on a comment.
I got the following (simplified) query:
var res = (from c in db.Comments
where c.Topic.ID == topicID
select new
{
comment = c,
count = c.CommentLikes.Count()
}).ToList();
But, rather than mapping the likecount into the comment entity again, I'd like to get a list of Comments only with a field LikeCount in it, preferably with an efficient query. Something like this:
var res = (from c in db.Comments
where c.Topic.ID == topicID
select new
{
comment = c,
c.LikeCount = c.CommentLikes.Count()
}).ToList();
This query doesn't compile.
How to do this in linq?
You can't do that. EF does not support to project (= select) data into an entity. You must fill the LikeCount property in memory after the query has been executed. You can write it in a compact way, but it's basically just a foreach loop over the materialized anonymous objects:
IEnumerable<Comment> res =
(from c in db.Comments
where c.Topic.ID == topicID
select new
{
comment = c,
count = c.CommentLikes.Count()
})
.ToList() // DB query runs here, the rest in memory
.Select(a => {
a.comment.LikeCount = a.count;
return a.comment;
});

Linq - How to query specific columns and return a lists

I am trying to write a linq query that will only return certain columns from my entity object into a list object.
Below is my code which produces an error(can't implicitly convert a generic list of anonymous types to a generic list of type TBLPROMOTION):
IQueryable<TBLPROMOTION> matches = webStoreContext.TBLPROMOTION.Include("TBLSTORE").Include("LKPROMOTIONTYPE");
List<TBLPROMOTION> promotionInfo = null;
promotionInfo = (from p in matches
orderby p.PROMOTION_NM descending
select new { p.EFFECTIVE_DT, p.EXPIRE_DT, p.IS_ACTIVE,
p.PROMOTION_DESC, p.PROMOTION_ID, p.PROMOTION_NM }).ToList();
What would be the best way to accomplish this. I do not want to do a "select p" in this case and return all the columns associated with the query.
thanks in advance,
Billy
Can't you do var promotionInfo = () and get a list of anonymous types?
Okay, basically you can not cast an Anonymous type to a known type like TBLPROMOTION.
ofcourse, you can say var promotionInfo = and then get an IEnumerable<{Anonymoustype}> and use that to do, what you were wanting to do with promotionInfo.
Also, personally I prefer the Fluent version of a linq query, easy on the eyes, good programming diet, at least for me :)
var promotionInfo = matches
.OrderByDescending( p => p.PROMOTION_NM)
.Select( p => new { p.EFFECTIVE_DT,
p.EXPIRE_DT,
p.IS_ACTIVE,
p.PROMOTION_DESC,
p.PROMOTION_ID,
p.PROMOTION_NM})
.ToList();
If you're moving from a L2E query to a Type already defined, you may need a step between. I haven't tried to compile this but something like:
List<TBLPROMOTION> promotions = new List<TBLPROMOTION>();
var results = from p in matches
orderby p.PROMOTION_NM descending
select new
{
p.EFFECTIVE_DT,
p.EXPIRE_DT,
p.IS_ACTIVE,
p.PROMOTION_DESC,
p.PROMOTION_ID,
p.PROMOTION_NM
};
foreach (var v in results)
{
promotions.Add(new TBLPROMOTION(v.EFFECTIVE_DT, v.EXPIRE_DT, v.IS_ACTIVE,
v.PROMOTION_DESC, v.PROMOTION_ID, v.PROMOTION_NM));
}
Based on the comment below, you might try something like:
foreach(var v in results)
{
TBLPROMOTION temp = new TBLPROMOTION();
temp.EFFECTIVE_DT = v.EFFECTIVE_DT;
temp.EXPIRE_DT = v.EXPIRE_DT;
temp.IS_ACTIVE = v.IS_ACTIVE
// Assign Other Properties
promotions.Add(temp);
}
.......
Sorry: Just read the addition to the top.
Are you sure that none of the fields you're leaving out (instead of saying "select p") are required for a TBLPROMOTION object? Also, sense your TBLPROMOTION object is going to have properties (and therefore memory allocated) for those skipped fields, why not just use an annonymous type or set up a helper class that contains only your needed properties?
#Billy, following code worked for me.
List<TBLPROMOTION> promotionInfo =
(from p in matches
orderby p.PROMOTION_NM descending
select new TBLPROMOTION(p.EFFECTIVE_DT, p.EXPIRE_DT, p.IS_ACTIVE,
p.PROMOTION_DESC, p.PROMOTION_ID, p.PROMOTION_NM)
).ToList();
did you try
select new TBLPROMOTION {.....
instead of
select new {.....
List<TBLPROMOTION> promotionInfo = null;
promotionInfo = (from p in matches
orderby p.PROMOTION_NM descending
select new TBLPROMOTION { COL1 = p.EFFECTIVE_DT, COL2 = p.EXPIRE_DT, COL3 = p.IS_ACTIVE... }).ToList();
Where COL1, COL2, ... are the names of the properties on TBLPROMOTION you wish you populate.
If you want a subset of the table you have 2 options:
#Fredou mentioned select new TBLPROMOTION{...}
other way is to create a custom DTO which has the exact properties & select them instead like:
List promotionInfo = ...
select new TBLPROMOTION_DTO{
Effective_dt = ...
}
HTH

How to write linq query based on EF?

Suppose I have three tables:
Person(pid, ...)
PersonAddress(pid, aid,...)
Address(aid, ...)
Then I want to get the person address like sql:
select a.* from address a join PersonAddress pa on a.addressID=pa.addressID
where pa.personID = myPersonID
Use Entity Framework to create Entity model, then want to write a linq equivalent as above sql.
I tried it in following way:
var addresses = this.GetAddress();
var personaddresses = this.GetPersonAddress();
var query = from ad in addresses
from pa in personaddresses
where ((ad.AddressID == pa.AddressID)&&(pa.PersonID==person.personID))
select ad;
but I got error. Or I try to start from:
var result = this.Context.Address;
var result = result.Join .... //how to write linq in this way?
How to write the linq?
This is untested but if you have all of your relationships setup and you create the model (I have used Model as the name for this) from this you should be able to use the following:
var values = this.Model.Address.Select(a => a.PersonAddress.Where(pa => pa.Id == myPersonID));
You almost never use join in LINQ to Entities.
Try:
var q = from p in Context.People
where p.PersonId == personId
from a in p.Addresses // presumes p.Addresses is 1..*
select a;
Assuming you have three entities: Person, PersonAddress and Address, here is a query that should meet your needs (this example assumes an Entity Framework context named context):
var values = context.PersonAddress.Where(pa => pa.Person.PersonId == myPersonId).Select(pa => pa.Address);
However, if the PersonAddress table exists as a pure many-to-many relationship table (i.e. contains only keys), you'd be better off setting up your Entity Framework model in such a way that the intermediate table isn't necessary, which would leave you with the much simpler:
var values = context.Person.Where(p => p.PersonId == myPersonId).Addresses;
Based on the additional feedback
Because you need to include the country table, you should originate your query from the Address table. In that case:
var values = context.Address.Where(a => a.PersonAddress.Where(pa => pa.Product.Id == myProductId).Count() > 0)
To include the Country table in the result:
var values = context.Address.Include("Country").Where(a => a.PersonAddress.Where(pa => pa.Product.Id == myProductId).Count() > 0)

Resources