3

My application has products and vendors and both of them have similar items in a "has a" relationship...in particular they have a "favorite" so users can bookmark them.

so we have:

public class Product
{
    public int ProductId {get;set;}
    public int Name {get;set;}
    public List<Favorite> Favorites {get;set;}
}

public class Vendor
{
    public int VendorId {get;set;}
    public int Name {get;set;}
    public List<Favorite> Favorites {get;set;}
}

public class Favorite
{
    public int FavoriteId {get;set;}
    public string UserName {get;set;}
}

At first this didn't work, so I added:

    public int? VendorId {get;set;}
    public int? ProductId {get;set;}

Now the issue I'm having is that my Vendor.Favorites and Product.Favorites are always null.

How do I bind these so that I can work with the objects like that? Do I not make it a separate entity?

Thanks!

UPDATE: I should note that I'm using MVC 3 Code-first with POCO.

UPDATE: Solution:

I don't think this is ideal, still working out the kinks with how I want this to work because It will add redundant code for adding favorites and reviews.

public class Product
{
    public int ProductId {get;set;}
    public int Name {get;set;}
    public virtual List<Favorite> Favorites {get;set;}
}

public class Vendor
{
    public int VendorId {get;set;}
    public int Name {get;set;}
    public virtual List<Favorite> Favorites {get;set;}
}

Having the raw nullable int variable in the favorites class makes it work, but if I wanted to use the favorites class with other objects I'll have to modify the favorites properties with a new mapping to the key of the object. Out of curiosity, when dealing with these classes normally, how do you manage the data storage for these objects? I'm assuming you deal with it at a DAL?

3 Answers 3

1

You could use inheritance, make a base class containing only Favorite then derive classes based on that for the other info. This establishes an "is a" relationship

Ex.

public class baseClass
{
 public list<Favorite> Favorites { get; set;}
}
public class Product : base
{
 public int ProductID { get; set; }
 public string Name { get; set; }
}

Then a Product Object would have all 3 properties.

Sign up to request clarification or add additional context in comments.

3 Comments

and then I could have other shared pieces like reviews and comments in the base class? I'll consider this change. Have you ever used this style? Do you have to do anything special to get the data into the entities?
Yes, anything you put in the base class can be utilized by any derived object as if it is a property of that object's class, it is completely transparent, and dynamic(you can convert between types and keep the common data.) I have used this style when using 2 very similar items that may differ only in one field. For example in a project at work I was dealing with parts and packages, they were the same except for the "packagenumber"/"partnumber" field. All fields except those went in a base class and then the "packagenumber"/"partnumber" went in the package and part classes, respectively.
How does the database differentiate between different classes? Does it have separate tables?
0

Based on the assumption that you're using EF 4.1:

Your model looks pretty good except I'd change

    public int? VendorId {get;set;}
    public int? ProductId {get;set;}

to

    public virtual Vendor VendorId {get;set;}
    public virtual Product ProductId {get;set;}

Then your FK relationships should be all set. By my understanding of EF, List<Favorite> is meant to establish a relationship and is not actually populated. You have to populate it yourself, either by calling .Include() on the context or by referencing the actual FK that EF creates in the database, which in your case would be VendorId_FavoriteId or ProductId_FavoriteId

1 Comment

This ended up being backwards, but got me in the right place. I need the int?'s so that the application can have a raw mapping and not have circular references (awful), I changed the public list<favorites> to public virtual list<favorites> and everyone was happy
0

I would keep one Property to store the ID's (either VendorID or ProductId) and use another property to tell me what type it is (Vendor or Product)

public class Favorite
{
    public int FavoriteId {get;set;}
    public string UserName {get;set;}
    public int ItemID { set;get;}    //can use a better generic name
    public FavoriteType Type { set;get;}
}

I have an Enum for the Types

public enum FavoriteType
{
    Vendor, 
    Product
}

And make sure you are initializing your sub properties before accessing them / applying a method on those so that It won't throw the null reference exception!. You can do it constructor itself

public class Product
{
    public int ProductId {get;set;}
    public int Name {get;set;}
    public List<Favorite> Favorites {get;set;}

  public Product()
  {
      if(Favourites==null)
          Favorites=new List<Favorite>();
  }
}

3 Comments

whether I go with the nullable foreign key or a discriminator field it's still not 100% extensible, but I'm okay with that. So I initialize the list, should I have to fill it or will MVC3 do it for me?
I disagree with the FavoriteType enum. The Favorite should not know it's type. This could potentially break the Liskov substitution principle. The context in which the favorites are retrieve will determine the favorite type. Also in the Product constructor it can be converted to a null coalesce Favorites ?? new List<Favorite>()
I added the null constructor and attempted use again. I checked the database, it has items in the favorites table that match up to items in the products table. When I reference the product's favorite, It says 0 count.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.