EF-код сначала 4.1: «Многократное наследование» (является а) вопрос

StackOverflow https://stackoverflow.com/questions/6049821

Вопрос

Я пытаюсь моделировать со своего рода «многократное наследование» отношения с кодом EF 4.1. Вот пример того, что я пытаюсь сделать.

Позвольте сказать, что я пытаюсь моделировать, как пользователь взаимодействует с моим приложением, используя объект «пользователя». Это, будучи базовым классом, используется для описания текущего пользователя, когда они ничего не делают в частности (например, посещение домашней страницы). Это может выглядеть так:

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 уже предпринят в таблице пользователя.

Есть ли способ моделировать это (ISA) отношения с EF-код первым? Или я собираюсь застрять с чем-то вроде этого?

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...
}
.

Я хотел бы сначала придерживаться кода и моделировать отношения прямо в моем DBContext, но я не могу понять, как это сделать что-то подобное. Спасибо!

Редактировать:

Так, я пытаюсь сделать что-то вроде этого:

public void SomeMethod ()
{
    var UserID = Guid.NewGuid ();
    var MyUser = new User () { ID = UserID };
    SaveUserToDatabase (MyUser);

    var ShopperRepresentation = GetUserAsShopper (UserID);
    //  Do stuff.
}
.

в основном нравится использовать объектно-ориентированные роли, я думаю. Я хочу использовать один и тот же PK для каждого представления этого пользователя, но хранить всю свою основную информацию в базовом классе, называемом пользователем. Я знаю, что это возможно, если я напишу свой собственный SQL, конечно, но я хочу посмотреть, может ли код EF сначала сделать это тоже.

Это было полезно?

Решение

Yes, you can do it the way you describe in your first two code examples.

I think you just need to define a mapping, which you'll want to do in your OnModelCreating function of your DataContext in addition to having your classes set up right. How you do it depends on what mapping scheme you're using. I went for Table-Per-Type (TPT) in my most recent project, so I had something like this:

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

Let me know if that doesn't work for you and I'll see what I can do.

Edit:

Having seen your clarification below, I can't think of a way to do that. You'd have to keep each objects stored separately (having EF treat a Shopper as just a Shopper, not a Shopper and a User), even though they share common data. That could lead to data mismatches (if, say, Shopper got its LastName updated but User didn't). I think you might be better off going with something like:

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; }
}

and then when you need to treat User as a Shopper, you just access the ShopperInfo (and if its not there, you create it). EF will be able to properly set that up for you no problem.

Though if you're going to have a lot of types of users, that might get cumbersome. Just a suggestion though - I think its a bit cleaner.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top