【发布时间】:2014-07-18 21:10:25
【问题描述】:
我希望使用 EF6 实现 Table-per-Hierarchy,类似于此处的说明: example.
我有一个 User 的抽象基类,它具有以下派生类型:
- 学生
- 联系方式
- 讲师
当我检查数据库表 Users 时,当我将学生对象传递到我的 时,discriminator 列的值为 (Undefined)保存方法如下。相反,我希望值是 Student。否则,我的数据会正确保存在 Users 和 Students 表中。
在解决问题时,我在类中添加了一个 UserType 枚举器 Get 属性,以确保我从 User 转换为 Student。
在我的 UserRepository 类中,我的 Save 方法如下。
public void Save(User user)
{
if (Exists(user.Id))
UpdateUser(user);
else
{
switch (user.Role)
{
case UserType.Role.Base:
_db.Users.Add(user);
break;
case UserType.Role.Student:
_db.Users.Add(user as Student);
break;
case UserType.Role.Instructor:
_db.Users.Add(user as Instructor);
break;
case UserType.Role.Contact:
_db.Users.Add(user as Contact);
break;
}
}
_db.SaveChanges();
}
失败的替代方案
我已经尝试过类似下面的代码来显式创建一个新的Student。
private void MapToStudent(User user)
{
_db.Users.Add(new Student()
{
FirstName = user.FirstName,
LastName = user.LastName,
//...
});
}
问题
我没有正确地向下转换?或者更确切地说,使用 EF 保存子类的正确/首选方法是什么?
用户基类
public abstract class User
{
public int Id { get; set; }
//...
}
internal class UserNotFound: User
{
public override UserType.Role Role
{
get
{
return UserType.Role.Base;
}
}
}
public class Student : User
{
//...
public override UserType.Role Role
{
get { return UserType.Role.Student; }
}
}
public class Contact : User
{
//...
public override UserType.Role Role
{
get { return UserType.Role.Contact; }
}
}
public class Instructor : User
{
//...
public override UserType.Role Role
{
get { return UserType.Role.Instructor; }
}
}
DatabaseContext 映射
public class DatabaseContext : Context
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().ToTable("Students");
modelBuilder.Entity<Contact>().ToTable("Contacts");
modelBuilder.Entity<Instructor>().ToTable("Instructors");
}
}
【问题讨论】:
-
我认为问题是你的基本类型不是抽象的。
-
@ErikPhilips 我的 User 类被指定为:
public abstract class User -
那么这段代码不应该存在:
case UserType.Role.Base: _db.Users.Add(user);。但是,user.Role的值是怎么设置的呢? -
internal class UserNotFound: User { public override UserType.Role Role { get { return UserType.Role.Base; } } }是我的 User 空对象的简单案例。我正在覆盖每个子类中的属性并根据其匹配的枚举值进行设置。对于@ErikPhilips -
为了将来参考,最好不要在评论中添加代码,而是向您的实际问题添加代码(您可以根据需要编辑它),以便其他阅读可以全面理解您的无需阅读所有 cmets 的问题。
标签: c# entity-framework inheritance downcast