Domanda

Sto cercando di modellare una sorta di relazione "più ereditanza" con il codice EF 4.1 prima. Ecco un esempio quello che sto cercando di fare.

Diciamo che sto tentando di modellare il modo in cui un utente interagisce con la mia applicazione utilizzando un oggetto "utente". Questo, essendo la classe base, viene utilizzato per descrivere l'utente corrente quando non stanno facendo nulla in particolare (come la visita della home page). Potrebbe sembrare così:

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

Ora, se voglio creare una rappresentazione di quello stesso utente, ma in una parte diversa del sito, ad esempio, come shopper, potrebbe sembrare così:

public class Shopper : User
{
    public virtual ICollection<Orders> Orders { get; set; }
}
.

E così via, e così via. Quando vado a inserire un acquirente che ha una voce utente preesistente, lancia un'eccezione perché il PK è già stato preso nella tabella utente.

C'è un modo per modellare questa relazione (ISA) con il codice EF prima? O sarò bloccato con qualcosa del genere?

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

Vorrei rimanere con il codice prima e modellare le relazioni proprio nel mio dbcontext, ma non riesco a capire abbastanza come fare qualcosa del genere. Grazie!

Modifica:

Quindi, sto cercando di fare qualcosa del genere:

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

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

fondamentalmente come usare ruoli orientati agli oggetti, immagino. Voglio usare lo stesso PK per ogni rappresentante di quell'utente, ma memorizza tutte le loro informazioni di base in una classe base chiamata Utente. So che questo è possibile se scrivo il mio sql, ovviamente, ma voglio vedere se il codice EF prima può farlo anche.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top