0

I have not worked with EF for a while. As an exercise, I am writing a core web api that allows keeping track of a user medias. A media can be a postcard, a photo album, a recording, a book...

I would like to know what is the way to go/best practice in writing the Add (createMedia) method:

[HttpPost]
public async Task<ActionResult<bool>> Add(Media media)

My model is comprised of several specific classes representing one type of media - like Postcard, Photoalbum, recording, etc. In addition, there is a Media type - which contains shared properties among all media types:

public class Media
{
    [Key]
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public MediaType Type { get; set; }
    public bool InUse { get; set; }
    public string Date { get; set; } //yyyy-mm-dd
    public string Owner { get; set; }
}

As an example of one of the specific media types:

public class Postcard
{
    [ForeignKey("Id")]
    public int MediaId { get; set; }
    public string From { get; set; }
    public string To { get; set; }
    public string Place { get; set; }
    public string Language { get; set; }

}

I designed my EntityFramework db to consist of a 1-1 relation between Media and the relevant specific media table.

What is the best practice in writing the Add method ? Should it receive a Media object, and based on MediaType create the respective type ? I started with this approach, and had the action receive a second parameter named detailsJson, which I would parse and fill the respective object using reflection, but figured out that POST binding will not bind 2 objects.

I'm not well versed in design patterns. Should there exist as many AddBook, AddPostcard... as many media types ? I understand all models should be POCO objects, without inheritance. I read about DTOs, but does not see how it helps me here.

  • Firstly, could you provide the code of the MediaType-Class/-Struct/-Enum? A Generic Media-Base-Controller, and an IMedia-Interface could help, to prevent duplicating code. – Nikolaus Jul 13 at 21:03
  • My concern was that POCO objects should not, theoretically have inheritance. I read this. I then realized I should be using composition in each of the specialized types adding a Media object as a navigation property to each. This way I achieve no code duplication while following EF practices. Am checking... – Veverke Jul 13 at 21:07
  • I understand, but that's not what I meant. If you could show the Code of your MediaType and of how theoretically your Post-Method would look like, I can show you in an answer, what I meant. – Nikolaus Jul 14 at 11:47
0

If there should be separate methods for adding postcards, books and so on depends on the business context of your application. Go back to the business requirements and see if:

  1. Adding media items is a primary or a side activity/requirement for the users
  2. Media of different types are explicitly distinguished- for example is there a business requirement stating that books should be added from one place, photos from another
  3. Is there any reason to worry about the way adding books is going to change from adding photos, for example

If you answer positively to these questions it would be wise to separate the adding methods for different media types.

Looking at the sample Media and PostCard models you've defined it looks like they should definitely be added separately as they consist of different data attributes and look like they could change at any given moment.

As a side note: Your Media model seems to be the principal in this relationship, but to me it looks like a pure value object which should be an attribute of the concrete media types. A redesign of your sample models could look like this:

public class MediaAttributesValueObject
{
    [Key]
    //kept as a persistance detail
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public bool InUse { get; set; }
    public string Date { get; set; } //yyyy-mm-dd
    public string Owner { get; set; }
}

public class PostcardEntity
{
    [Key]
    public int Id { get; set; }
    [ForeignKey("Id")]
    public int MediaAttributesValueObjectId { get; set; }
    public MediaType Type => MediaType.PostCard
    public string From { get; set; }
    public string To { get; set; }
    public string Place { get; set; }
    public string Language { get; set; }

}

Note that I've added ValueObject and Entity suffixes to highlight model types

The relationship would still be configured as 1-to-1, but in the opposite way with the specific type of being the principal.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.