Using IN subquery in Entity Framework using Linq - entity-framework

I have the following tables in my database:
- Reservation
- TrainStation
- Train
- Traveller
- Reservation_Traveller
- TrainSeats: Attributes are: Train_Id, Seat, Traveller_Id
I want to find the TrainSeats rows of a particular Reservation
I have a Reservation object that contains an ICollection<Traveller> property containing the travellers of which I want to remove their seats from the TrainSeats table. I fetched the reservation object from the database like this:
var reservation = db.Reservation.Where(r => r.Id == id).FirstOrDefault();
So I want to do something like this:
db.TrainSeats.Where(ts => ts.Traveller_Id IN reservation.Travellers)

First select the travelers id:
var ids=reservation.Travellers.Select(e=>e.Id);
Then use Contains extension method which is translated into IN in sql:
var query=db.TrainSeats.Where(ts => ids.Contains(ts.Traveller_Id));
I guess if you use the FK property and navigation properties you can do it in one query:
var query= db.Travellers.Where(e=>e.ReservationId==id).SelectMany(t=>t.TrainSeats);

Related

Not able to use IN query in LINQ with Entity Framework

I am using EF Framework to retrieve the data from SQL DB.
Sub Request Table looks like below:
In this table "org_assigneddept" is foreign key to another Department Table.
I have list of Departments as Input and I want to retrieve only those rows from DB whose org_assigneddept is matching the list.
Please find my whole code:-
private List<EventRequestDetailsViewModel> GetSummaryAssignedDeptEventRequests(List<EmpRoleDeptViewModel> vmDept)
{
List<EventRequestDetailsViewModel> vmEventRequestDeptSummary = new List<EventRequestDetailsViewModel>();
RequestBLL getRequestBLL = new RequestBLL();
Guid subRequestStatusId = getRequestBLL.GetRequestStatusId("Open");
using (var ctxGetEventRequestSumm = new STREAM_EMPLOYEEDBEntities())
{
vmEventRequestDeptSummary = (from ers in ctxGetEventRequestSumm.SubRequests
where vmDept.Any(dep=>dep.DeptId == ers.org_assigneddept)
select new EventRequestDetailsViewModel
{
SubRequestId = ers.org_subreqid
}).ToList();
}
}
It is giving the following error at the LINQ Query level:-
System.NotSupportedException: 'Unable to create a constant value of
type 'Application.Business.DLL.EmpRoleDeptViewModel'. Only primitive
types or enumeration types are supported in this context.'
Please let me know as how can I achieve the result
You cannot pass the department VMs to SQL, it doesn't know what those are.
// Extract the IDs from the view models.. Now a list of primitive types..
var departmentIds = vmDept.Select(x => x.DeptId).ToList();
then in your select statement...
..
where departmentIds.Contains(id=> id == ers.org_assigneddept)
..

OrderBy Expression When Using An Association Table

I have two tables: CommentCategories and Comments. It is a many-to-many relationship. There is a CommentCategory_Comment association table. But that table contains a orderOfCommentInCategory field, so EF represents the association by creating a seperate entity rather than navigation properties.
I am trying to get the comments under a certain category and orer them by the orderOfCommentInCategory field. How should be the OrderBy expression that needs to be added to the query below?
List<Comment> comments = category.CommentCategory_Comment
.Select(ccc=>ccc.Comment)
.OrderBy(???)
.ToList();
As #GertArnold recommends the only you need to do is order first before select:
var comments = category.CommentCategory_Comment
.OrderBy(c=>c.orderOfCommentInCategory )
.Select(ccc=>ccc.Comment)
.ToList();
Using query syntax:
var query= from cc in category.CommentCategory_Comment
orderby cc.orderOfCommentInCategory
select cc.Comment;
var comments=query.ToList();

Using entity framework to get info from three connected tables

I got products table
->productID - primary
->price
->Quantity
productCategory -table
->prodcatID- primary
->prodId - foreign key
->catID - foreign key
productlanguages - table
->prodID - foreign key
->langID - forein key
->Title
So I use Entity framework and I shoud somehow get all products WITH THEIR TITLE,QUANTITYI PRICE From GIVEN CATEGORY AND FROM GIVEN LANGUAGE.
SO i should somehow combine info from all these three table
so i made my first function to get all products from given category
public List<ProductCategories> GetAllProductsForCategory(int catID)
{
using (OnlineStoreDBContext db = new OnlineStoreDBContext())
{
List<ProductCategories> lst = db.ProuctCategories.Where(x => (x.CategoryID == catID)).ToList();
}
}
So now I have a list with all productID that match this category. But now how to get the data from the other two.
See Loading Related Entities: http://msdn.microsoft.com/en-au/data/jj574232.aspx

Entity Framework: selecting from multiple tables

I have a statement:
var items = from e in db.Elements
join a in db.LookUp
on e.ID equals a.ElementID
where e.Something == something
select new Element
{
ID = e.ID,
LookUpID = a.ID
// some other data get populated here as well
};
As you can see, all I need is a collection of Element objects with data from both tables - Elements and LookUp. This works fine. But then I need to know the number of elements selected:
int count = items.Count();
... this call throws System.NotSupportedException:
"The entity or complex type 'Database.Element' cannot be constructed in a LINQ to Entities query."
How am I supposed to select values from multiple tables into one object in Entity Framework? Thanks for any help!
You are not allowed to create an Entity class in your projection, you have to either project to a new class or an anonymous type
select new
{
ID = e.ID,
LookUpID = a.ID
// some other data get populated here as well
};
Your code doesn't work at all. The part you think worked has never been executed. The first time you executed it was when you called Count.
As exception says you cannot construct mapped entity in projection. Projection can be made only to anonymous or non mapped types. Also it is not clear why you even need this. If your class is correctly mapped you should simply call:
var items = from e in db.Elements
where e.Something == something
select e;
If LookupID is mapped property of your Element class it will be filled. If it is not mapped property you will not be able to load it with single query to Element.

navigating many-to-many via include in EF4

I have a many to many relationship in EF4 with the following entities:
[Student] - [Class] - [Student_Class]
Moreover i have a [School] entity with a FK on [Student].
If i want to have all the Students of my school i do:
context.School.Include("Student")
but if i want to have the 1rst class of my Students in my school ?
context.School.Include("Student").Include("Student_Class").Where(...
i did not manage to make this thing work...
Can you help ?
Also is it more intelligent to write a full Linq select?
Thanks
John
If you want to do a conditional eager load, then you should NOT be using the Include method.
For loading your school object containing only the students that belong to the first class
You can do a Filtered Projection which returns an Anonymous Type object:
var school = context.School
.Where(s => s.SchoolID == 1) // or any other predicate
.Select(s => new
{
School = s,
Students = s.Student.Where(st => st.ClassID == 1)
}).ToList();
Another way would be to Leverage Attach Method which returns EntityObject:
var school = context.School.Where(s => s.SchoolID == 1).First()
var sourceQuery = school.Students.CreateSourceQuery()
.Where(st => st.ClassID == 1);
school.Students.Attach(sourceQuery);
For a more detailed discussion about this, you can also check:
Entity Framework: How to query data in a Navigation property table