gpt4 book ai didi

c# - 使用 Entity Framework 代码保存分离的对象图首先导致违反主键

转载 作者:太空宇宙 更新时间:2023-11-03 10:54:14 25 4
gpt4 key购买 nike

我正在尝试使用 Code First 流利符号保存已映射到 EF6 的 POCO 的对象图。

然而,在保存对象图时,我偶然发现了主键违规异常。

对象图非常简单:

一个Issue可以包含多个WorkItems,每个Author(作为User)。

对象在外部填充(使用 Web API)

当我尝试用引用同一作者的两个工作项保存问题时,我希望插入问题、插入工作项和插入一位作者,然后引用或引用另一位作者已更新。

但是发生的是问题被插入,工作项被插入并且对同一用户的两个引用被插入,导致主键冲突。

简化的问题对象:

public class Issue
{
public Issue()
{
WorkItems = new List<WorkItem>();
}

public string Id { get; set; }

private List<WorkItem> _workItems;
public List<WorkItem> WorkItems
{
get { return _workItems ?? new List<WorkItem>(); }
set { _workItems = value; }
}
}

简化的工作项:

public class WorkItem
{
public string Id { get; set; }

public string AuthorLogin
{
get; set;
}

private WorkItemAuthor _author;
public WorkItemAuthor Author
{
get { return _author; }
set { _author = value;
if (value != null)
{
AuthorLogin = value.Login;
}
else
{
AuthorLogin = string.Empty;
}
}
}
}

简化的用户对象:

public class User
{
public string Login { get; set; }
public string FullName { get; set; }
}

他们的代码优先配置:

    internal IssueConfiguration()
{
HasKey(x => x.Id);
HasMany(x => x.WorkItems);
}
internal WorkItemConfiguration()
{
HasKey(x => x.Id);

HasRequired(p => p.Author)
.WithMany(b => b.WorkItems)
.HasForeignKey(x=>x.AuthorLogin);
}
internal UsersConfiguration()
{
HasKey(x => x.Login);
}

一切都非常简单。创建数据库后,de tables 看起来也很好,花花公子,在人们期望的列上有 FK

现在,在保存问题时,如果插入对象图会很好,并且可以自动识别对现有对象的引用,并且可以选择插入或仅引用。

我尝试相应地添加问题:

using (var db = new Cache.Context())
{
if (db.Issues.Any(e => e.Id == issue.Id))
{
db.Issues.Attach(issue);
db.Entry(issue).State = EntityState.Modified;
}
else
{
db.Issues.Add(issue);
}
db.SaveChanges();
}

这个问题的解决方案是我遍历对象图以手动添加或附加图中的其他对象吗?我希望通过定义适当的外键值来识别这些引用。

最佳答案

我终于做了类似的事情,很费力,我还是想找到更好的方法。查明一个实体是否已经附加或存在于数据库中被证明会过多地污染模型(实现 IEquatable<T> 很好,但我认为在我的 POCO 上实现 IEntityWithKey 会过度污染 POCO。(直到那个在上下文中似乎不足以跟踪实体)

internal static void Save(this List<Issue> issues)
{
using (var db = new Context())
{
foreach (var issue in issues.ToList())
{

foreach (var workItem in issue.WorkItems.ToList())
{
if (workItem.Author != null)
{
var existing = db.Users.SingleOrDefault(e => e.Login == workItem.Author.Login);
if (existing == null)
{
db.Users.Add(workItem.Author);
}
else
{
//Update existing entities' properties
existing.Url = workItem.Author.Url;

//Replace reference
workItem.Author = existing;
}
db.SaveChanges();
}

var existingWorkItem = db.WorkItems.SingleOrDefault(e => e.Id == workItem.Id);
if (existingWorkItem == null)
{
db.WorkItems.Add(workItem);
}
else
{
//Update existing entities' properties
existingWorkItem.Duration = workItem.Duration;

//Replace reference
issue.WorkItems.Remove(workItem);
issue.WorkItems.Add(existingWorkItem);
}

db.SaveChanges();
}


var existingIssue = db.Issues.SingleOrDefault(x => x.Id == issue.Id);
if (existingIssue == null)
{
db.Issues.Add(issue);
}
else
{
//Update existing entities' properties
existingIssue.SpentTime = issue.SpentTime;
}

db.SaveChanges();
}
}
}

关于c# - 使用 Entity Framework 代码保存分离的对象图首先导致违反主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20098287/

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