【发布时间】:2019-04-15 08:49:31
【问题描述】:
我正在尝试使用实体框架将基对象转换为派生类对象。
我尝试使用复制构造函数。构造函数本身确实可以工作,但框架会抛出错误。
模型类:
public class Member
{
[Key]
public string SRU { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public virtual Address Address { get; set; }
}
public class Player : Member
{
public virtual PlayerPosition Position { get; set; }
public virtual Doctor Doctor { get; set; }
public virtual HealthIssue HealthIssue { get; set; }
public Player()
{
}
public Player(Member m)
{
SRU = m.SRU;
Name = m.Name;
Email = m.Email;
Address = m.Address;
}
}
我的尝试:
DatabaseModel db = new DatabaseModel();
var val = db.Members
.FirstOrDefault(b => b.Name == "Frank");
val = new Player(val);
db.Members.Update(val);
// Save changes in database
db.SaveChanges();
我希望更新此实体,但它会引发错误:
System.InvalidOperationException: '无法跟踪实体类型'Player'的实例,因为另一个具有相同键值的实例 {'SRU'} 已被跟踪。
附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
编辑:
我试过了,但我改了名字,但类型还是一样。
DatabaseModel db = new DatabaseModel();
var val = db.Members
.FirstOrDefault(b => b.Name == "Yordan");
db.Entry(val).State = EntityState.Detached;
var val2 = new Player(val);
val2.Name = "Frank";
db.Members.Update(val2);
db.SaveChanges();
所以我得到了会员和播放器扩展会员。在这种情况下,我想将 Member 转换为 Player。
【问题讨论】:
-
首先,这似乎是 EF Core,所以请更新标签。其次,这听起来像是设计不当或 XY 问题。
val已经是Player并且不清楚您要更新什么,或者是另一个Member派生类型,在这种情况下它无法转换为Player。请描述一下你到底想做什么。 -
需要将成员更改(扩展)为播放器,通常在编程中使用复制构造函数,但 EF 不允许我这样做。
-
这不是正常的编程,因为您选择将所有
Member派生类型存储在一个表 (TPH database inheritance strategy) 中,SRU是主键,所以它是唯一的。这就是 EF 错误消息试图告诉您的内容。 -
好的,我明白了。这个数据库首先是由代码完成的。知道如何重新设计它吗?或如何更改
Discriminator
标签: asp.net-mvc entity-framework