gpt4 book ai didi

entity-framework - 实体不公开外键属性的 DbUpdateException

转载 作者:行者123 更新时间:2023-12-04 07:57:13 26 4
gpt4 key购买 nike

我有一个实体模型 UserPerson实体,这样每个 User必须正好与 1 Person 相关联, 和每个 Person可以关联零或 1 User .

User (0..1) <-------> (1) Person

关联映射流畅。最初我只在 Person 上声明了它边:
private class PersonOrm : EntityTypeConfiguration<Person>
{
internal PersonOrm()
{
ToTable(typeof(Person).Name, DbSchemaName.People);

// has zero or one User
HasOptional(p => p.User)
.WithRequired(d => d.Person)
.Map(d => d.MapKey("PersonId"))
.WillCascadeOnDelete(false)
;

由于我遇到了这个错误,我也在 User中添加了相同的映射边:
private class UserOrm : EntityTypeConfiguration<User>
{
internal UserOrm()
{
ToTable(typeof(User).Name, DbSchemaName.Identity);

// has exactly 1 Person
HasRequired(p => p.Person)
.WithOptional(d => d.User)
.Map(d => d.MapKey("PersonId"))
.WillCascadeOnDelete(false);

应用中有一个场景,新 User可以创建并与现有 Person 相关联.这是我目前遇到困难的地方。英孚正在考虑 User作为关系的依赖方,并放置一个 PersonId (FK, int, not null) User上的专栏 table 。我不相信可以在任一实体上使用外键属性来帮助 EF 管理关联(是吗?)。

这是一些尝试处理该场景的失败代码:
// find out if Person already exists
var person = context.People.SingleOrDefault(p => p.Emails.Any(
e => e.Value.Equals(emailAddress, StringComparison.OrdinalIgnoreCase)));

// find out if User already exists
var user = context.Users.SingleOrDefault(
u => u.Name.Equals(emailAddress, StringComparison.OrdinalIgnoreCase));

if (user == null)
{
user = new User
{
Name = emailAddress,
IsRegistered = isRegistered,
Person = person ?? PersonFactory.Create(emailAddress),
// ignore the PersonFactory.Create, that part works
};

context.Entry(user).State = EntityState.Added;
context.SaveChanges();
}

person 时,此代码工作正常为空(数据库中尚不存在)。然而当 person不为空(已存在于数据库中)和 user为空,代码尝试创建一个新的 User并将其与现有 Person 相关联.调用时 SaveChanges() , 我得到一个 DbUpdateException :

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.



内部异常是:

A relationship from the 'User_Person' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'User_Person_Source' must also in the 'Deleted' state.



这对我来说没有任何意义,因为我不想删除任何内容,而是检查 EntityState两者的 UserPerson显示 UserAdded状态,而 PersonUnchanged状态。我已覆盖 SaveChanges()展示:
public override int SaveChanges()
{
var userChanges = ChangeTracker.Entries<User>().Single();
var personChanges = ChangeTracker.Entries<Person>().Single();

if (userChanges.State == EntityState.Deleted)
throw new InvalidOperationException("wtf?");

if (personChanges.State == EntityState.Deleted)
throw new InvalidOperationException("wtf?");

return base.SaveChanges();
}

当这段代码执行时, InvalidOperationException被抛出。再次, userChangesAdded状态,和 personChangesUnchanged状态。

我究竟做错了什么?

最佳答案

我现在真的觉得很傻。写完这个仔细的问题后,现在很明显了。
Person我正在测试已经存在,并且已经有 User与不同的关联 User.Name .这就是为什么user即将为空。设置 Person.User新的属性(property)User是造成老User放入 Deleted状态。多。

很抱歉浪费了您的时间。我会留下这个问题,除非大家同意删除它会更好。

关于entity-framework - 实体不公开外键属性的 DbUpdateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10113323/

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