0

我正在尝试使用 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; }
}

等等等等。当我插入具有预先存在的用户条目的购物者时,它会引发异常,因为 PK 已经在用户表中。

有没有办法用 EF Code First 来模拟这种(IsA)关系?还是我会被这样的事情困住?

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 是否也能做到。

4

1 回答 1

1

是的,您可以按照您在前两个代码示例中描述的方式进行操作。

我认为您只需要定义一个映射,除了正确设置您的类之外,您还希望在您的OnModelCreating功能中执行该映射。DataContext你如何做取决于你使用的映射方案。我在最近的项目中选择了 Table-Per-Type (TPT),所以我有这样的东西:

modelBuilder.Entity<User>().ToTable("Users");
modelBuilder.Entity<Shopper>().ToTable("Shoppers");
modelBuilder.Entity<OtherUser>().ToTable("OtherUsers");

如果这对你不起作用,请告诉我,我会看看我能做些什么。

编辑:

看到你在下面的澄清后,我想不出办法做到这一点。您必须将每个对象单独存储(让 EF 将 Shopper 视为仅 Shopper,而不是 Shopper 和 User),即使它们共享公共数据。这可能会导致数据不匹配(例如,如果 Shopper 更新了 LastName 但 User 没有更新)。我认为您最好使用以下方法:

public class User
{
    public virtual Guid ID { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual ShopperInfo { get; set; }
}

public class ShopperInfo
{
    public virtual ICollection<Order> Orders { get; set; }
}

然后当您需要将用户视为购物者时,您只需访问 ShopperInfo(如果它不存在,则创建它)。EF 将能够为您正确设置,没问题。

但是,如果您要拥有多种类型的用户,那可能会很麻烦。不过只是一个建议-我认为它更干净一些。

于 2011-05-18T19:33:35.880 回答