Although you forgot to specify, it seems to me that every Foo
has zero or more Props
, and every Prop
belongs to exactly one Foo
: a standard one-to-many relation. It could be a many-to-many relation, the answer will be similar.
Apparently you want to remove all Props
from one or more Foos
. Entity framework is nt designed to fetch and change data in one database access. You'll have to fetch the objects you want to change, change the values of one or more properties of the fetched objects and then call SaveChanges()
.
If you want to fetch-change-save in one function, you'll have to write a stored procedure.
The Entity Framework Method
If you have followed the entity framework code first conventions you'll have something like:
class Foo
{
public int Id {get; set;}
...
// every Foo has zero or more Props (one-to-many)
public virtual ICollection<Prop> Props {get; set;}
}
class Prop
{
public int Id {get; set;}
...
// every Prop belongs to exactly one Foo using foreign key:
public int FooId {get; set;}
public virtual Foo Foo {get; set;}
}
One would expect that once you'd have fetched a Foo
it would be enough to call foo.Props.Clear()
:
var fetchedFoos = dbContext.Foos.Where(foo => ...);
foreach (var fetchedFoo in fetchedFoos)
{
fetchedFoo.Props.Clear();
}
Alas, as is stated in this Stackoverflow article, ICollection.Clear()
does not work in entity framework (at least not in the older versions. I haven't checked it lately).
If you want to get rid of all Props
of a given Foo
, you'll have to delete them by Prop.FooId
Create the query that will fetch all Foos
of which you want to clear the Props
collection. Do not execute the query yet:
var fooIds = myDbContext.Foos
.Where(foo => ...)
// I don't need the complete `Foo`, I only need the `Id`
.Select(foo => foo.Id);
I want to remove all Props
that have a FooId
that is somewhere in fooIds
:
var propsToDelete = dbContext.Props
.Where(prop => fooIds.Contains(prop.FooId));
Query still not executed!
Now delete the props:
dbContext.Props.RemoveRange(propsToDelete);
dbContext.SaveChanges();
If desired, you can concatenate the LINQ into one big statement. As no queries are executed until the RemoveRange / SaveChanges I doubt whether this would improve efficiency. It surely will deteriorate readability, and thus testability / maintainability