我想通过Linq和EF选择一个列表。
问题是,如果我使用延迟加载,然后尝试清除链接到另一个表(foo.prop.clear()
)的属性,则会花费很长时间(返回到数据库)。
如果我使用.include(x => x.props)
,它将返回链接表中的所有行,这也需要很多时间。
由于链接表可能会更改,因此我不想使用.Select()
选项。
有没有办法使foo.prop
已经为空,或者更快地清除列表?
谢谢。
答案 0 :(得分:0)
尽管您忘记指定,但在我看来,每个Foo
都有零个或多个Props
,而每个Prop
恰好属于一个Foo
:一个标准的对多关系。可能是多对多关系,答案将是相似的。
显然您要从一个或多个Props
中删除所有Foos
。实体框架的设计目的是在一次数据库访问中获取和更改数据。您将必须获取要更改的对象,更改获取的对象的一个或多个属性的值,然后调用SaveChanges()
。
如果要在一个函数中进行读取-更改-保存,则必须编写一个存储过程。
如果您遵循entity framework code first conventions,将会看到类似的内容:
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;}
}
人们希望一旦您获取了Foo
,就可以调用foo.Props.Clear()
:
var fetchedFoos = dbContext.Foos.Where(foo => ...);
foreach (var fetchedFoo in fetchedFoos)
{
fetchedFoo.Props.Clear();
}
A,as is stated in this Stackoverflow article,ICollection.Clear()
在实体框架中不起作用(至少在较旧的版本中不起作用。我最近没有对其进行检查)。
如果要删除给定Props
的所有Foo
,则必须通过Prop.FooId
删除它们
创建查询,该查询将提取您要清除Foos
集合的所有Props
。暂不执行查询:
var fooIds = myDbContext.Foos
.Where(foo => ...)
// I don't need the complete `Foo`, I only need the `Id`
.Select(foo => foo.Id);
我想删除所有Props
中位于FooId
中的fooIds
的所有var propsToDelete = dbContext.Props
.Where(prop => fooIds.Contains(prop.FooId));
:
dbContext.Props.RemoveRange(propsToDelete);
dbContext.SaveChanges();
查询仍未执行!
现在删除道具:
body {
background: #ccc;
}
input {
background: transparent;
border: none;
}
如果需要,可以将LINQ连接成一个大语句。因为直到RemoveRange / SaveChanges都没有执行查询,所以我怀疑这是否会提高效率。它肯定会降低可读性,从而降低可测试性/可维护性