通过Linq和EF选择带有链接表的空列表

时间:2018-08-19 20:02:23

标签: c# asp.net entity-framework linq

我想通过Linq和EF选择一个列表。

问题是,如果我使用延迟加载,然后尝试清除链接到另一个表(foo.prop.clear())的属性,则会花费很长时间(返回到数据库)。

如果我使用.include(x => x.props),它将返回链接表中的所有行,这也需要很多时间。

由于链接表可能会更改,因此我不想使用.Select()选项。

有没有办法使foo.prop已经为空,或者更快地清除列表?

谢谢。

1 个答案:

答案 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 articleICollection.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都没有执行查询,所以我怀疑这是否会提高效率。它肯定会降低可读性,从而降低可测试性/可维护性