Entity Framework: Deleting multiple objects query - entity-framework

I have a List which hold the PK ID's of a number of objects in a collection that I want to remove. Does anyone know how to write a single query to retrieve these objects?
Eg:
IList<int> objectList; // populated with int Primary key Ids
using (MyEntities context = new MyEntities()){
var result = context.MyObjectCollection.Where(obj=> obj.ID IN objectList);
foreach(var item in result){
context.DeletObject(item);
}
context.SaveChanges();
}
Any help would greatly be appreciated!

var result = context.MyObjectCollection.Where(obj=> objectList.Contains(obj.ID));

Mel's answer doesn't work because in .NET 3.5 SP1 the EF doesn't know how to translate list.Contains(...) into T-SQL. Although this is coming in 4.0.
The workaround is to manually produce a big OR query i.e.
Where(obj => obj.ID == item1 || obj.ID == item2 ....)
Here is a tip I wrote that makes that easy:
Tip 8 - How to write where IN style queries using LINQ to Entities
Hope this helps
Alex James
Entity Framework Team - Read my Entity Framework Tips

http://efe.codeplex.com
this.Devices.Update(o => new Device() { LastOrderRequest = DateTime.Now, Description = "teste" }, o => o.Id == 1);

Related

How to Data Fetch using Entity Framework in dotnet core

I have a table called "UserAnswers".below screenshot contains table data
I want to get data by surveyId and group by CreatedBy column.
for an example
There is a user called "amara#gmail.com".this user contains 4 records for a SurveyId.
I want to get this like below
Answers : [
{"2"},
{"1","0","1","1"},
{"1","2","4","3"},
{"Blue"}]
But my code returns this array for every rows.I meant duplicate records returning.
Here is my code
var qstns = await (from uans in _context.UserAnswers
where uans.SurveyId == id
select new UserAnswersReturnDto
{
UserEmail = uans.CreatedBy,
Qustns = (from ans in _context.UserAnswers
where ans.CreatedBy == uans.CreatedBy
select new UserAnswersSet
{
QNo = ans.QNo,
Ansrs = JsonConvert.DeserializeObject<JArray>(string.IsNullOrEmpty(ans.Answers) ? "[]" : ans.Answers)
}).ToArray()
}).ToListAsync();
So how to solve this issue.I opened many questions for this problem,but no one answered.Please help me.Thanks in advanced
You need to actually group your data before returning:
I used LINQ Lambda notation, but it should be quite easy to translate back to query if you're so inclined:
var qstns = _context.UserAnswers.Where(uans => uans.SurveyId == id)
.GroupBy(uans => uans.CreatedBy)
.Select(grans => new UserAnswersReturnDto {
UserEmail = grans.Key,
Qustions = grans.Select(ans => new UserAnswersSet() {
QNo = ans.QNo,
Ansrs = ans.Answers
}).ToList()
} ).ToList();
I didn't have time to double-check this, but I hope it serves as a guide to help you solve your issue!
There is no group by statement in your linq query.

Brute force collection in Entity Framework

Good day to all!
There is such a code
var userRoles = context.UserRoles.Where(ur => ur.UserId == id);
if (userRoles.Any())
{
context.UserRoles.RemoveRange(userRoles);
}
var userCars = context.UserCars.Where(uc => uc.UserId == id);
It is necessary to get rid of the extra SELECT code before deleting:
context.UserRoles.RemoveRange (userRoles);
How to do it better?
If RemoveRange loops through the incoming collection, then for each record in the UserCars collection, a separate query will be executed into the database, which is bad. The sample should be within the same request:
var userCars = context.UserCars.Where (uc => uc.UserId == id);
How to do it better?
Sincerely, Mikhail
if i understand right you want to perform the select and the delete in one query
i think this should help you Entity Framework Plus
Batch Delete

Nested Where on 1-to-many in LINQ2Entity

I'm using EF4. Having 2 entities:
Person { Name }
Hobbys { Person.Name, IsCoolHobby }
1 Person can have several hobbys.
I now have
IQueryable<Person> p;
p = container.PersonSet.Include("Hobbys").AsQueryable();
p = p.Where(x => x ?????);
List<Person> tmp = p.ToList();
How can i return only those Persons who have cool hobbys (IsCoolHobby == true)? I tried join but i was not able to load them into the list (select can only return Person, Hobby or new Type - but how to map them to entity objects again?)
Thanks
How can i return only those Persons who have cool hobbys (IsCoolHobby
== true)?
List<Person> tmp = container.PersonSet.Include("Hobbys")
.Where(p => p.Hobbys.Any(h => h.IsCoolHobby))
.ToList();
This will load the people who have at least one cool hobby but the Hobbys collection for those people will always contain all hobbys, also the uncool hobbys.
Edit
Unfortunately filtering and sorting children during eager loading (Include) is currently not supported. There is a request on the EF feature suggestion page for this feature. The request has status "Under review", so there is a little hope that it might get implemented in the future. (Probably far future: At least the first docs about EF 5 (beta) on MSDN say explicitly that eager loading with filtering/sorting is still not implemented.)
For now there are only two workarounds. The first is to use a projection:
var projectedData = container.PersonSet
.Where(p => p.Hobbys.Any(h => h.IsCoolHobby))
.Select(p => new
{
Person = p,
CoolHobbys = p.Hobbys.Where(h => h.IsCoolHobby)
})
.ToList();
The result is a collection of anonymous objects which contain a user who has cool hobbys and a collection of those cool hobbys. If you don't disable change tracking (by using the NoTracking option for the query) the person's hobbys collection should be filled with the result automatically.
The second option is to use "explicit" loading with CreateSourceQuery:
List<Person> tmp = container.PersonSet
.Where(p => p.Hobbys.Any(h => h.IsCoolHobby))
.ToList();
foreach (var person in tmp)
{
person.Hobbys.Attach(person.Hobbys.CreateSourceQuery()
.Where(h => h.IsCoolHobby).ToList());
}
Two things to note here:
CreateSourceQuery is only available on EntityCollections, i.e. if you are using EntityObject derived entities. It's not available for POCO entities in EF 4.0. (EF >= 4.1/DbContext has the option for explicit loading also for POCOs -> Query() method.)
The above code represents 1+N roundtrips to the database: The first for the person collection without the hobbys and then one additional query per person to load the cool hobbys.

ADO.NET Entity Framework multiple statement in where clause or a grouped lambda expression

I am new to the ADO.NET Entity Framework Model. Using DotNet Framework 3.5
I have two tables :
viz. customers and city
The customers table refers to a cityname column in the table city (foreign key relationship)
While creating a win c# form i am giving the user to filter customers based on his search choices (viz. name, city, number, etc.) Here is my structure
using(DataContext dc = new DataContext())
{
IEnumerable cust = dc.customers;
if(name != null) {
cust = cust.Where<customers>(c => c.name == name);
}
if(mobile != null) {
cust = cust.Where<customers>(c => c.mobile == mobile);
}
if(city != null) {
cust = cust.Where<customers>(c => c.city.cityname == city); //ERROR HERE
}
}
I get a NullPointerException, since the EntityReference.Load method is not called upon. Quite logical point and I agree to it.
I would like some advice on how to either call the load method in the current architechure. Is it possible to somehow do this :
c.cityReference.Load();
c.city.cityname == city
Or possibly some lambda expression (I am new to it) which induces both the statements? Ne suggestions?
I am ready to change the current architecture if anyone has a better advice.
Try
IEnumerable cust = dc.customers.Include("city");
Check out this post for reference.

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