1

This is a little exercise I've been doing to get used to coding with the "Code First"-approach. I actually would have set this up faster if I would have done it "conservatively" "Database First", I suppose, but then I would not have gotten any taste of this new stuff so I wanted to give it a try. These are the entities that I need in my application:

  • Item (pretty much only a title, a description and an id, additional information might follow)
  • ItemPrice (as the title tells this shall represent an item's price at a certain time, so this needs to be able to reference an item and also store a DateTime-value and a Decimal for the price)
  • ItemRecipe (this contains a way an item can be created, there might be different ways to construct an item, that's why this is not part of the Item-class itself, so this references a target item and a list of tuples [of Item/Amount pairs])

Now for inserting and updating items and prices, this works for me, my problem is with the recipes; I cannot yet grasp how I need to write the recipe-POCO (I think virtual for the containing list may even be wrong)

I wrote the POCO-classes:

Item:

public class Item
{
        public int ID { get; set; }

        [Required(ErrorMessage = "Please enter a title for this item.")]
        [MaxLength(127)]
        public string Title { get; set; }

        [Required(ErrorMessage = "Please enter a descriptive text for this item.")]
        [MaxLength(4000)]
        public string Description { get; set; }
}

ItemPrice:

    [DataContract]
    public class ItemPrice
    {
        public int ID { get; set; }

        [Required(ErrorMessage = "You need to select an item for this price.")]
        [DataMember(IsRequired = true)]
        public int ItemID { get; set; }

        [ForeignKey("ItemID")]
        public virtual Item Item { get; set; }

        [Required(ErrorMessage = "You need to set a price for this item.")]
        [DataMember(IsRequired = true)]
        public Decimal Price { get; set; }

        [Required(ErrorMessage = "You need to provide a date and time for the price for this item.")]
        [DataMember(IsRequired = true)]
        public DateTime Time { get; set; }
    }

ItemRecipe:

    [DataContract]
    public class ItemRecipe
    {
        public int ID { get; set; }

        [Required(ErrorMessage = "You need to select an item for this recipe.")]
        [DataMember(IsRequired = true)]
        public int ItemID { get; set; }

        [ForeignKey("ItemID")]
        public virtual Item TargetItem { get; set; }

        public virtual List<Tuple<Item, int>> Ingredients { get; set; }
    }

So can anyone point me to how I need to set this up? Also how would I tell this list of tuples that its item-part actually references an existing item that must not appear twice in the list? Can this even be done with data annotations only? If not what do I need?

Basically I just want to access recipes like the other entities in this project, I use a generic repository to retrieve/manipulate values. The api-controllers I use just have simple Get-/Post-/Put-/Delete-methods so for updating or creating a recipe I would just go with overriding it(not insert the ingredient item-amounts one by one).

DrCopyPaste
  • 4,023
  • 1
  • 22
  • 57
  • List won't work - and not w/o fluent configuration in the code. In short, I think you need `ItemItemRecipe` index table, many-to-many - which has composite Item, ItemRecipe ID-s + the tag-along 'int' for the part amount. For that you need to do it in the code, no way to do that via annotations. You can check my earlier post on how to do it [EF code-first many-to-many with additional data](http://stackoverflow.com/a/10199455/417747) – NSGaga-mostly-inactive Jun 06 '13 at 14:33
  • aaaw, well i feared that already, but thanks for the input anyway :) could you expand a bit more on what an index table is and how i set it up? – DrCopyPaste Jun 06 '13 at 14:38
  • it's what you get I think :) - if nothing better comes along and if this helped let me know to post an answer - or let me know if problems with fluent and I'll explain some more. Cheers – NSGaga-mostly-inactive Jun 06 '13 at 14:40
  • one thing to clarify, if I now go with using fluent api, I won't be able to use the data annotations at all, right? Because I override the DBContext's OnModelCreating? – DrCopyPaste Jun 06 '13 at 14:50
  • 1
    no, they work in unison - you can combine, just not recommended to combine features that do the same thing. YOu can consider the 'fluent config' like an additional configuration. Truth is I only use fluent, once you get used to it, as I prefer to have all the config in one place, but that's just nicer, not that you can't do it. – NSGaga-mostly-inactive Jun 06 '13 at 15:29

0 Answers0