我试图用EF 4.1 Code First模拟一种“多重继承”关系。这是我想要做的一个例子。
假设我试图模拟用户使用“用户”对象与我的应用程序交互的方式。作为基类,它用于描述当前用户没有特别做任何事情时(例如访问主页)。它可能看起来像这样:
public class User
{
public Guid ID { get; set; } // Just use the forms authentication user ID
public string FirstName { get; set; }
public string LastName { get; set; }
}
现在,如果我想创建同一个用户的代表,但在网站的不同部分,比如说,作为购物者,它可能看起来像这样:
public class Shopper : User
{
public virtual ICollection<Orders> Orders { get; set; }
}
等等,等等。当我去插入具有预先存在的User条目的Shopper时,它会引发异常,因为PK已经在User表中被采用。
有没有办法模拟这个(IsA)与EF Code First的关系?或者我会被这样的事情困住?
public class Shopper
{
public Guid UserID { get; set; }
public virtual User User { get; set; }
public virtual ICollection<Order> Orders { get; set; }
public string FirstName
{
get { return User.FirstName; }
set { User.FirstName = value; }
}
// yada, yada, yada...
}
我想坚持使用Code First并在我的DbContext中建立关系模型,但我无法弄清楚如何做这样的事情。谢谢!
修改
所以,我试图做这样的事情:
public void SomeMethod ()
{
var UserID = Guid.NewGuid ();
var MyUser = new User () { ID = UserID };
SaveUserToDatabase (MyUser);
var ShopperRepresentation = GetUserAsShopper (UserID);
// Do stuff.
}
我猜基本上就像使用面向对象的角色一样。我想为该用户的每个代表使用相同的PK,但是将所有基本信息存储在名为User的基类中。我知道如果我编写自己的SQL,这是可能的,当然,我想看看EF Code First是否也可以这样做。
答案 0 :(得分:1)
是的,您可以按照前两个代码示例中的描述进行操作。
我认为您只需要定义一个映射,除了让您的类设置正确之外,您还需要在OnModelCreating
的{{1}}函数中执行该映射。你如何做到这取决于你正在使用的映射方案。我在最近的项目中选择了Table-Per-Type(TPT),所以我有这样的事情:
DataContext
如果这对您不起作用,请告诉我,我会看到我能做些什么。
修改强>
看了下面的说明,我想不出办法做到这一点。您必须将每个对象分开存储(让EF将购物者视为购物者,而不是购物者和用户),即使它们共享公共数据。这可能会导致数据不匹配(例如,如果Shopper更新了LastName,但用户没有更新)。我认为你可能会更喜欢这样的事情:
modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Shopper>().ToTable("Shoppers");
modelBuilder.Entity<OtherUser>().ToTable("OtherUsers");
然后当您需要将User视为购物者时,您只需访问ShopperInfo(如果不存在,则创建它)。 EF将能够为您正确设置,没问题。
虽然如果你有很多类型的用户,那可能会很麻烦。只是一个建议 - 我认为它有点清洁。