【问题标题】:EF Code First 4.1: "Multiple Inheritence" (Is A) QuestionEF Code First 4.1:“多重继承”(Is A)问题
【发布时间】:2011-05-18 19:10:05
【问题描述】:

我正在尝试使用 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 是否也能做到。

【问题讨论】:

    标签: c# ef-code-first oop object-oriented-database


    【解决方案1】:

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

    我认为您只需要定义一个映射,除了正确设置您的类之外,您还希望在您的OnModelCreating 函数中执行该映射。你如何做取决于你使用的映射方案。我在最近的项目中选择了 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 将能够为您正确设置,没问题。

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

    【讨论】:

    • @Tim - 感谢您的回复!我可以很好地创建表格。我想做的是创建一个用户,然后插入它。然后,例如,稍后将同一用户用作购物者。 PK 是表单身份验证提供的用户 ID。因此,根据用户正在做什么,他们将有一个不同的对象来代表他们。因此,用户对象不会包含有关他们购物体验的任何内容,但他们的客户版本会。
    • 从你所说的......你是在创建 User 对象的实例......然后有时还创建 Shopper 的实例?
    • @Tim - 是的,取决于他们访问的页面。这是同一个“人”使用相同的 PK,但对他们正在做什么/他们能够做什么的表示不同。
    • 好的,基于此,我编辑了我的推荐。不确定你会喜欢它。但我不知道如何沿着你正在寻找的方向走得更远。
    • @Tim - 作为对您的编辑的回应,我害怕这就是我必须做的。我认为值得花时间在 SO 周围钓鱼,看看其他人是否有不同的看法。我会等着看其他人是否有意见,如果没有更好的意见,给你答案。感谢您的宝贵时间!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多