【问题标题】:Select via Linq and EF with empty list for linked tables通过 Linq 和 EF 选择链接表的空列表
【发布时间】:2018-08-19 20:02:22
【问题描述】:

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

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

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

我不想使用.Select() 选项,因为链接表可以更改。

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

提前致谢。

【问题讨论】:

  • 相当于懒加载:)
  • 什么?发出删除语句来删除您要清除的行绝不是延迟加载。
  • 我不想删除。只是为了清除 foo.props 列表并用我自己的数据替换。清除需要很长时间。
  • 如果你想打破引用,你实际上会清除一个表字段。这也可以通过更新语句快速完成。 EF 可能不知道许多更新可以简化为一个 - 你可以。 “替换”是另一种东西,因为它是插入,它可能需要更长的时间。但是你是否破坏了一个强制性的引用,你需要删除引用实体,否则你会得到异常。

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


【解决方案1】:

尽管您忘记指定了,但在我看来,每个Foo 都有零个或多个Props,并且每个Prop 恰好属于一个Foo:标准的一对多关系。可能是多对多的关系,答案也差不多。

显然您想从一个或多个Foos 中删除所有Props。实体框架的设计目的是在一次数据库访问中获取和更改数据。您必须获取要更改的对象,更改所获取对象的一个​​或多个属性的值,然后调用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();
}

唉,as is stated in this Stackoverflow articleICollection.Clear() 在实体框架中不起作用(至少在旧版本中不起作用。我最近没有检查过)。

如果您想删除给定Foo 的所有Props,则必须通过Prop.FooId 删除它们

创建将获取您要清除Props 集合的所有Foos 的查询。暂时不要执行查询:

var fooIds = myDbContext.Foos
    .Where(foo => ...)
    // I don't need the complete `Foo`, I only need the `Id`
    .Select(foo => foo.Id);

我想删除所有在fooIds 中具有FooIdProps

var propsToDelete = dbContext.Props
    .Where(prop => fooIds.Contains(prop.FooId));

查询仍未执行!

现在删除道具:

dbContext.Props.RemoveRange(propsToDelete);
dbContext.SaveChanges();

如果需要,您可以将 LINQ 连接成一个大语句。由于在 RemoveRange / SaveChanges 之前没有执行任何查询,我怀疑这是否会提高效率。它肯定会降低可读性,从而降低可测试性/可维护性

【讨论】:

  • 感谢您的回答。但我不想保存任何更改。只需清除代码端的道具列表并添加新项目。我先用 DB。
猜你喜欢
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
相关资源
最近更新 更多