gpt4 book ai didi

asp.net-mvc - 我可以在不加载整个集合的情况下删除单个子实体吗?

转载 作者:行者123 更新时间:2023-12-01 10:38:45 25 4
gpt4 key购买 nike

我有 2 个类,如下所示。

他们可以拥有非常大的集合 - 一个网站可能有 2,000 多个网站页面,反之亦然。

  class WebsitePage 
{
public int ID {get;set;}
public string Title {get;set;}
public List<Website> Websites {get;set;}
}

class Website
{
public int ID {get;set;}
public string Title {get;set;}
public List<WebsitePage> WebsitePages {get;set;}
}

我无法从网站中删除 WebsitePage。特别是当从多个网站中删除一个网站时。

例如,我可能有这样的代码:
var pageToRemove = db.WebsitePages.FirstOrDefault();
var websites = db.Websites.Include(i => i.WebsitePages).ToList();
foreach(var website in websites)
{
website.WebsitePages.Remove(pageToRemove)
}

如果每个网站 Include() 有 2k 个页面,您可以想象加载第二行需要很长时间。

但是,如果我在获取网站时不对网站页面进行 Include() 编码,则没有加载的子集合可供我删除。

我试图对我需要删除的页面进行 Include() 编码,但当然在保存时会给我一个空集合。

有没有推荐的或更好的方法来解决这个问题?

我正在使用现有的 MVC 站点,除非绝对必要,否则我宁愿不必 create an entity class for the join table

最佳答案

不,你不能……正常情况下。
多对多关系(带有隐藏的连接表)只能通过添加/删除嵌套集合中的项目来影响。为此,必须加载集合。
但是有一些选择。
选项1。
通过原始 SQL 从联结表中删除数据。基本上这看起来像

context.Database.ExecuteSqlCommand(
"DELETE FROM WebsiteWebsitePage WHERE WebsiteID = x AND WebsitePageID = y"));
(不使用参数)。
选项 2。
将结点包含到类模型中,即将结点表映射到类 WebsiteWebsitePage .两者 WebsiteWebsitePage现在将有
public ICollection<WebsiteWebsitePage> WebsiteWebsitePages { get; set; }
WebsiteWebsitePage将具有对 Website 的引用属性和 WebsitePage .现在您可以直接通过类模型操作连接点。
我认为这是最好的选择,因为一切都发生在与验证和跟踪等实体一起工作的标准方式。此外,您可能迟早会需要一个显式连接类,因为您将要向其中添加更多数据。
选项 3。
技巧之盒。
我试图通过从集合中删除 stub 实体来做到这一点。在您的情况下:创建一个 WebsitePage具有有效主键值的对象并将其从 Website.WebsitePages 中删除无需加载集合。但是 EF 没有注意到变化,因为它没有跟踪 Website.WebsitePages ,并且该项目一开始不在集合中。
但这让我意识到我必须让 EF 轨道成为 Website.WebsitePages包含 1 个项目的集合,然后删除该项目。我通过首先构建 Website 开始工作item 然后将它附加到一个新的上下文。我将展示我使用的代码(标准 Product - Category 模型)以防止输入错误。
Product prd;

// Step 1: build an object with 1 item in its collection
Category cat = new Category { Id = 3 }; // Stub entity
using(var db = new ProdCatContext())
{
db.Configuration.LazyLoadingEnabled = false;
prd = db.Products.First();
prd.Categories.Add(cat);
}

// Step 2: attach to a new context and remove the category.
using(var db = new ProdCatContext())
{
db.Configuration.LazyLoadingEnabled = false;
db.Products.Attach(prd);

prd.Categories.Remove(cat);

db.SaveChanges(); // Deletes the junction record.
}
延迟加载被禁用,否则当 prd.Categories 时仍然加载类别被解决。
我对这里发生的情况的解释是:在第二步中,EF 不仅会在您附加产品时开始跟踪产品,还会开始跟踪产品的关联,因为它“知道”您无法在多对多关系中自行加载这些关联。但是,当您在第一步中添加类别时,它不会这样做。

关于asp.net-mvc - 我可以在不加载整个集合的情况下删除单个子实体吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31628182/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com