gpt4 book ai didi

asp.net-mvc - 如何优雅地重新附加 Entity Framework 5 POCO 结构并保存它?

转载 作者:行者123 更新时间:2023-12-03 16:14:16 25 4
gpt4 key购买 nike

我正在使用 Entity Framework 5(具有生成的 POCO 的数据库优先)来制作 MVC4 Web 应用程序以进行数据访问。

在应用程序中,用户浏览多个屏幕,创建或编辑文档(称为“案例研究”)。当他们到达最终屏幕时,他们的文档作为 CaseStudy POCO 存在于内存中,一切都很好,直到需要将此结构保存到数据库中。

为了存储文档,我定义了几个数据库表,这些表依次映射到业务层使用的 EF POCO,然后由 MVC Controller 使用。因此,短期 DbContext 用于检索 POCO 并将它们存储在请求之间的 session 中。

因此,保存屏幕必须将具有导航属性的 POCO 内容保存到现有表数据(Category、Layout 和 Sections 表),以及添加或更新的数据(CaseStudySections 和 CaseStudy 本身)。因此,所有 POCO 要么是新的,要么用于检索它们的上下文早已被处置。换句话说,它们都是“分离的”。

这篇文章的不同寻常之处在于我已经有了一个可行的解决方案。问题是它笨重、易碎且不优雅。我在下面发布代码。注意通过子集合的迭代,显式添加和附加,必须获取一个条目对象并将单个属性标记为已修改,以便它们将被更新,以及最后的可怕歌曲和舞蹈以使 AdditionalMaterials 集契约(Contract)步。如果这是在 EF5 中处理分离的 POCO 所需要的,我会感到失望。

我在这里错过了什么吗?这与最佳实践一致吗?是否有更优雅和/或更简洁的方法来附加 POCO 结构和插入/更新?

保存案例研究的代码:

public void SaveCaseStudy(CaseStudy caseStudy)
{
foreach (var s in caseStudy.CaseStudySections)
{
this.Entities.Sections.Attach(s.Section);

if (s.CreatedByRefId == default(Guid))
{
s.CreatedByRefId = this.UserRefId;
s.CreatedTime = DateTime.Now;
this.Entities.CaseStudySections.Add(s);
}
else
{
this.Entities.CaseStudySections.Attach(s);
var entry = this.Entities.Entry(s);
entry.Property(e => e.TextData).IsModified = true;
entry.Property(e => e.BinaryData).IsModified = true;
}

s.LastModifiedByRefId = this.UserRefId;
s.LastModifiedTime = DateTime.Now;
}

foreach (var m in caseStudy.AdditionalMaterials)
{
if (m.CreatedByRefId == default(Guid))
{
m.CreatedByRefId = this.UserRefId;
m.CreatedTime = DateTime.Now;
this.Entities.AdditionalMaterials.Add(m);
}
else
{
this.Entities.AdditionalMaterials.Attach(m);
}

m.LastModifiedByRefId = this.UserRefId;
m.LastModifiedByTime = DateTime.Now;
}

this.Entities.Layouts.Attach(caseStudy.Layout);
this.Entities.Categories.Attach(caseStudy.Category);

if (caseStudy.CreatedByRefId != default(Guid))
{
this.Entities.CaseStudies.Attach(caseStudy);
var entry = this.Entities.Entry(caseStudy);
entry.Property(e => e.CaseStudyName).IsModified = true;
entry.Property(e => e.CaseStudyTitle).IsModified = true;
}
else
{
this.Entities.CaseStudies.Add(caseStudy);
caseStudy.CreatedByRefId = this.UserRefId;
caseStudy.CreatedTime = DateTime.Now;
}

caseStudy.LastModifiedByRefId = this.UserRefId;
caseStudy.LastModifiedTime = DateTime.Now;

if (caseStudy.CaseStudyStatus != (int)CaseStudyStatus.Personalized)
{
caseStudy.CaseStudyStatus = (int)CaseStudyStatus.PendingApproval;
}

caseStudy.ApprovedByRefId = null;
caseStudy.ApprovedTime = null;
this.Entities.SaveChanges();

var existingAdditionalMaterialRefIds = caseStudy.AdditionalMaterials
.Select(m => m.AdditionalMaterialRefId)
.ToArray();

var additionalMaterialsToRemove = this.Entities.AdditionalMaterials
.Where(m =>
m.CaseStudyRefId == caseStudy.CaseStudyRefId &&
!existingAdditionalMaterialRefIds.Contains(m.AdditionalMaterialRefId))
.ToArray();

foreach (var additionalMaterialToRemove in additionalMaterialsToRemove)
{
this.Entities.AdditionalMaterials.Remove(additionalMaterialToRemove);
}

this.Entities.SaveChanges();
}

最佳答案

一般来说,这是你必须做的。在附加分离的对象图时,您必须告诉 EF 您要执行的每个更改。我并不是说你的代码不能被简化,但如果你想添加或修改它,你仍然需要处理每个实体并设置它的状态。

Here有点旧但仍然是关于该主题的有效答案 - 简而言之,自从我编写它以来没有任何变化,只创建了新的 DbContext API,它仍然位于旧 API 之上。到目前为止,我看到的关于这个主题的最佳描述是在书 Programming Entity Framework: DbContext 中。 .

关于asp.net-mvc - 如何优雅地重新附加 Entity Framework 5 POCO 结构并保存它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12402024/

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