Reputation: 2889
I can't wrap my mind around this issue and haven't found the correct search keys yet:
I would like to have several categories
of items
in which all items
have specific attributes
. Those attributes
(text fields, dropdowns, or checkboxes) should be added to a category
and I want to edit and save those attributes
for each item
.
I'm working with MVC 4 and code-first EF5. How can I implement this?
My first approach were several classes like Text
, Dropdown
that were inherited from an abstract Attribute
class and a Category
class like this:
public class Category
{
[Key]
public int CategoryId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Item> Items { get; set; }
public virtual ICollection<Attribute> Attributes { get; set; }
}
But then I had no idea to proceed. Am I on the right way or completely wrong? Can someone give me a few hints I can search for?
Edit
Ultimately I'm trying to build a list of hifi devices. Speakers have different attributes than amplifier and those have different attributes to tape recorders. I would like to give a unified look for the details of each device and pre-define specific attributes to that category with an additional free-for-all text area. Speaker XYZ is my item
, Speaker my category
and dB an attribute
.
Upvotes: 0
Views: 487
Reputation: 2714
I actually never worked with code first approach, but I can give you some idea about how this scenario can be handled...To me, it looks that Item
is the major one instead of Category
. So you can have this structure...
public class Category
{
[Key]
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string CategoryDescription { get; set; }
// use attributes here if you want them for Category
//public Dictionary<string, string> ItemnAttributes { get; set; }
}
public class MyItem
{
[Key]
public int ItemId { get; set; }
public string ItemName { get; set; }
public string ItemDescription { get; set; }
public Category ItemnCatagory { get; set; }
public Dictionary<string, string> ItemnAttributes { get; set; }
}
Hope this helps..
Upvotes: 1
Reputation: 14312
I think something like this may work for you...
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Item> Items { get; set; }
public virtual ICollection<Attribute> Attributes { get; set; }
}
public class Item
{
public int ItemId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public virtual ICollection<ItemAttribute> ItemAttributes { get; set; }
}
public class Attribute
{
public int AttributeId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<ItemAttribute> ItemAttributes { get; set; }
}
public class ItemAttribute
{
public int ItemId { get; set; }
public int AttributeId { get; set; }
public Item Item { get; set; }
public Attribute Attribute { get; set; }
public string Value { get; set; }
public int ValueInt{ get; set; }
// etc.
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ItemAttribute>()
.HasKey(x => new { x.ItemId, x.AttributeId });
modelBuilder.Entity<ItemAttribute>()
.HasRequired(x => x.Item)
.WithMany(x => x.ItemAttributes)
.HasForeignKey(x => x.ItemId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<ItemAttribute>()
.HasRequired(x => x.Attribute)
.WithMany(x => x.ItemAttributes)
.HasForeignKey(x => x.AttributeId)
.WillCascadeOnDelete(false);
// AttributeCategories is created for you - but you can do the same as ^ above to customize
// just change 'ICollection<Category> Categories' to collection of 'ItemAttribute'
}
// use it like e.g.
var item = new Item { Name = "ItemTest", };
var attribute = new Attribute { Name = "attributeTest", };
item.ItemAttributes = new List<ItemAttribute>
{
new ItemAttribute { Item = item, Attribute = attribute, Value = "test", },
};
var category = new Category
{
Name = "cat1",
Items = new[]
{
item,
new Item{ Name = "Item1", },
new Item{ Name = "Item2", },
new Item{ Name = "Item3", },
new Item{ Name = "Item4", },
new Item{ Name = "Item5", },
},
Attributes = new[]
{
attribute,
new Attribute{ Name = "att1", },
new Attribute{ Name = "att2", },
}
};
db.Categories.Add(category);
db.SaveChanges();
var categories = db.Categories.ToList();
ItemAttribute
is used to connect and store values
.
And you're going to need to further adjust as per your requirements.
Upvotes: 1
Reputation: 4643
Ok so this question is basically about the data design.
First, I assume that the rule is:
For rule no.1, it is good enough in your design. (simplified example)
public class Category{
public IEnumerable<Item> Items{get;set;}
}
public class Item{
public Category Category{get;set;}
}
Its clear enough.
For rule no.2, I think you should make a CategoryAttribute class. It holds the relation between one to many Category and Attribute. Basically, CategoryAttribute is a master, whereas the children will be ItemAttribute.
public class Category{
public IEnumerable<CategoryAttribute> CategoryAttributes{get;set;}
}
public class CategoryAttribute{
public Category Category{get;set;}
public string CategoryName{get;set;}
public string DefaultValue{get;set;} // maybe a default value for specific
// attribute, but it's up to you
public IEnumerable<ItemAttribute> ItemAttributes{get;set;}
}
The IEnumerable<ItemAttribute>
is the one to many relation between category attribute and item attribute.
For rule no.3, the the ItemAttribute described in rule no.2 will be represented attribute owned by each item.
public class Item{
public IEnumerable<ItemAttribute> ItemAttributes{get;set;}
}
public class ItemAttribute{
public Item Item {get;set;} // it owned by one attribute
public CategoryAttribute{get;set;} // it owned by one category attribute
}
I don't quite sure about how to represent relation or primary and foreign key in code first. Hopefully I can enhance my answer if needed (and if I able). But hopefully my illustration about relations and the class designs for each objects.
Upvotes: 1