【发布时间】:2012-10-11 15:53:49
【问题描述】:
我使用的是 EF Code First,并定义了两个类,如下所示:
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
[Table("Visitors")]
public class Visitor : User
{
public Visitor()
{
Favourites = new List<Building>();
}
public virtual IList<Building> Favourites { get; set; }
}
这使用 Table-Per-Type 继承并定义 DB 架构如下:
Users Table
Id int PK
Username nvarchar(max)
Email nvarchar(max)
Visitors Table
Id int PK (FK to Users table)
这正是我想要的结构。 现在我的问题是,如果我创建一个用户对象并将其保存到数据库中,我以后如何能够将其扩展为访问者(如果需要?)我是否需要删除用户并创建一个新的访问者,或者我可以如何将用户转换为访问者对象,并且用户表中的条目将保持不变,并且将新条目添加到引用用户的访问者表中?类似下面的代码?
Context.Set<User>().Add(new User(){Id=1, Username="Bob", Email="bob@mail.bob"});
Context.SaveChanges();
//and elsewhere in the project I want to do this sort of thing:
Context.Set<Visitor>().Where(v=>v.Id == 1).FirstOrDefault().Favourites.Add(someFavouriteBuilding); //This obviously doesn't work, because the FirstOrDefault call returns null, so it will throw an exception
Context.SaveChanges();
//or maybe this can be modified slightly to work?:
var visitor = Context.Set<Visitor>().Where(v=>v.Id == 1).FirstOrDefault();
if (visitor==null)
{
visitor = new Visitor(Context.Set<User>().Where(u=>u.Id == 1).FirstOrDefault()); // this contructor copies all the property values accross and returns a new object
}
visitor.Favourites.Add(someFavouriteBuilding); //This obviously doesn't work either
var entry = Context.Entry(visitor);
entry.State = EntityState.Modified;//here it throws this error: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
Context.SaveChanges();
我认为,如果我只能将上面代码中的第二种方法正确附加到上下文中,它可能会起作用。无论如何,上面的代码只是向您展示我想要实现的目标。我知道这行不通。谁能提出更优雅的方法?
谢谢
【问题讨论】:
标签: c# .net entity-framework ef-code-first table-per-type