Should I inherit from a Model when creating a ViewModel - asp.net-mvc

I want to create a ViewModel, which is almost identical to the underlying Model, but with 2 added attributes. As an example, I have a Model named Person and the ViewModel would then look like:
public class PersonVM : Person
{
public string Subscription {get; set;}
public int? OtherAttribute {get; set;}
}
Is this the most optimal scenario or should I not inherit, but include it in the class like this?
public class PersonVM
{
public Person Person {get; set;}
public string Subscription {get; set;}
public int? OtherAttribute {get; set;}
}
The advantage of inheritance would be maintainability and ease of coding. When calling an attribute in the first scenario would be direct e.g. PersonVM.LastName, while in the second scenario the same call would be longer and potentially confusing: PersonVM.Person.LastName. What should be the considerations when choosing between these alternatives?

Related

Entity Framework using foreign key as only primary key in one to many

I am using Entity Framework code first to design the database.
I have 2 models with One to Many relationship. One "Foo" can have many "FooData" as follows -
public class Foo {
[Key]
public string serialNumber{get; set;}
public int someNumber {get; set;}
public string someName {get; set;}
// Many more properties
// Navigation Collection
public virtual ICollection<FooData> FooDatas{get; set;}
}
public class FooData{
[Key]
[ForeignKey("foo")]
public string SerialNum {get; set;}
public DateTime SomeTime {get; set;}
public byte[] SomeData {get; set;}
// Navigation property
public virtual Foo foo {get; set;}
}
When I try to add a controller for "Foo" in MVC, using "Foo" as a scaffolding model, it gives me this error - "Multiplicity is not valid in Role. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be 1".
I would appreciate some help here.
Thank you
Because of how you have it defined the same key is used in both so it is a 1-to-1 relationship. If you want a real one to many you will need to add/create another field and set them up as a composite key on the FooData table/entity.
public class Foo {
[Key]
public string serialNumber{get; set;}
public virtual ICollection<FooData> FooDatas{get; set;}
}
public class FooData {
[Key, Column(Order = 0),ForeignKey("foo")]
public string SerialNum {get; set;}
[Key,Column(Order=1)]
public int DataId {get;set;}
public virtual Foo foo {get; set;}
}

Multiple one-to-one relationships to same table

Which is the best way to model multiple one-to-one relationships to a same table (sqlite-net-extensions)? I am looking for a solution like this:
Class WayBill
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
[ForeignKey(typeof(Organization ))]
public int ConsignerId {get; set;}
[OneToOne]
public Organization Consigner {get; set;}
[ForeignKey(typeof(Organization ))]
public int ConsigneeId {get; set;}
[OneToOne]
public Organization Consignee {get; set;}
}
Class Organization
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public string Name {get; set;}
}
Obviously, the above won't work.
I have considered other options too:
create a table (WayBillOrganization) that captures the role of organization:
Waybill -->> WayBillOrganization --> Organization
put the required inverse OneToMany properties in to the Organization.
Handle things manually (ie. store only primary keys in the WayBill class and load the Organizations separately).
Option 2. is something I want to avoid. Organizations are related to so many other classes (not in my example) and even in the case of a waybill, there's a few more relationships I didn't include into the example (carrier, cargo paying party, freight forwarder and so on). Besides, I'd rather use inverse properties only when I need to navigate (for example, I don't use organization to find waybills, so an inverse property is only an extra burden.)
Option 3. isn't that attractive either.
So the option 1. seems to be the way to go. But before going there, I'd like to know if the perfect-world solution in my example is indeed impossible.
So, my question is: Is there a way to model multiple one directional OneToOne relationships without explicitly declared inverse properties?
Your use case is supported in SQLite-Net Extensions. You only have to specify the foreign keys explicitly in the relationship attributes, because automatic discovery may not work as expected:
class WayBill
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public int ConsignerId {get; set;}
[OneToOne("ConsignerId")]
public Organization Consigner {get; set;}
public int ConsigneeId {get; set;}
[OneToOne("ConsigneeId")]
public Organization Consignee {get; set;}
}
class Organization
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public string Name {get; set;}
}
Inverse relationships to the same class are also supported, but must be also declared explicitly at both ends:
class WayBill
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public int ConsignerId {get; set;}
[OneToOne(foreignKey: "ConsignerId", inverseProperty: "ConsignerInverse")]
public Organization Consigner {get; set;}
public int ConsigneeId {get; set;}
[OneToOne(foreignKey: "ConsigneeId", inverseProperty: "ConsigneeInverse")]
public Organization Consignee {get; set;}
}
class Organization
{
[PrimaryKey, AutoIncrement]
public int Id {get; set;}
public string Name {get; set;}
[OneToOne(foreignKey: "ConsigneeId", inverseProperty: "Consignee")]
public WayBill ConsigneeInverse { get; set; }
[OneToOne(foreignKey: "ConsignerId", inverseProperty: "Consigner")]
public WayBill ConsignerInverse { get; set; }
}

Usage of entities and DTOs when performing read and create/update on a database

What is the proper usage of entities and DTOs when performing database actions? My mindset is that it seems best to use DTOs when reading from a database and entities when creating/updating to a database. As a small example let's consider teh following:
Book Class
public class Book/Entity
{
public int Id {get; set;}
public string Title {get; set;}
public int AuthorId {get; set;}
public Author Author {get; set;}
}
Author Class/Entity
public class Author
{
public int Id {get; set;}
public string Name {get; set;}
public int BookId {get; set;}
public Book Book {get; set;}
}
BookAuthorDto Class
public class BookAuthorDto
{
public string Title {get; set;}
public string Name {get; set;}
}
Now, let's say we have a WebApi Book controller.
public class BookController : ApiController
{
public IHttpActionResult GetBook(int id)
{
var BADto = context.Book.Where(book => book.ID == id)
.Select(book => new BookAuthorDto
{
Title = book.Title,
Name = book.Author.Name
});
return Ok<BookAuthorDto>(BADto);
}
public IHttpActionResult PostBookEntity(Book book)
{
// Code for saving book to DB
}
public IHttpActionResult PostBookDto(BookAuthorDto BADto)
{
// Code for creating entities from DTO
// Code for saving the created entities to Database
}
}
Which method is considered more "proper" the PostBookEntity method, or the PostBookDto Method?
Actually it is a good idea to separate queries from data modifications (insert, update, delete) - this is called Command Query Responsibility Segregation pattern (CQRS).
Here are some great posts from experts
An introduction to CQRS by M.Fowler
Some good reasoning on why Entities + Dto's are better than just using Entities for all cases
Entities pretty much are DTOs. Use the entity for all database access, and use view models in your actions.

Is there a design pattern to standardise the display of multiple models into a single view?

I've tinkered with derived classes, interfaces and viewmodels, but I haven't been able to create quite what I need.
Say we're building a CMS with the following models:
ArticleItem
Title
Summary
Content
NewsItem
Headline
PublishDate
Summary
Content
EventItem
EventTitle
StartDate
EndDate
Content
I'm looking for a way to standardise the display of these into one format / view (e.g. so we can display them all in the same RSS feed). The standardized view might be called HTMLItem and have 3 fields:
Title
Summary
Content
The ArticleItem would translate directly to the HTMLItem, that's straightforward.
For the NewsItem I would like to join the PublishDate and the first 100 characters of the content to create Summary field of HTMLItem.
For the EventItem I would like to combine the StartDate and EndDate to create the Summary field of HTMLItem.
Ultimately I'm looking for the easiest, most efficient way to be able to pass the 3 models into a single view that has been designed to display HTMLItem. My best shot so far has been to create a 'convertor' class for each model, but I can't help feeling that there is a better way to do this.
Any experience, expertise and advice would be much appreciated!
Make a ViewModel with the standarized properties and a constructor for each specialized class:
public class HtmlItemViewModel {
//Properties
public string Title {get; set;}
public string Summary {get; set;}
public string Content {get; set;}
//Constructor inside HtmlItemViewModel for each one of the specialized classes:
public HtmlItemViewModel(ArticleItem item)
{
this.Title = item.Title;
this.Summary = item.Summary;
this.Content = item.Content;
}
public HtmlItemViewModel(NewsItem item)
{
this.Title = item.Headline;
this.Summary = String.Format("{0} - {1}", item.PublishDate, item.Summary.Substring(0,1000));
this.Content = item.Content;
}
public HtmlItemViewModel(EventItem item)
{
this.Title = item.EventTitle;
this.Summary = String.Format("{0} - {1}", item.StartDate, item.EndDate);
this.Content = item.Content;
}
}
Then, on the method you use for your RSS Feed simply pass each entity to the constructor on each individual query. Like this:
//Example controller
public class RssController : Controller {
public ActionResult GetRssFeed(){
//Assuming you have a service for each item type
var articleList = ArticleService.GetArticles().Select(s => new HtmlItemViewModel(s));
var newsItemList = NewsItemService.GetNewsItems().Select(s => new HtmlItemViewModel(s));
var eventItemList = EventItemService.GetEvents().Select(s => new HtmlItemViewModel(s));
articleList.AddRange(newsItemList);
articleList.AddRange(eventItemList);
return articleList;
}
}
You can use Viewmodel Pattern in your project
Models and ViewModels are different. Don't confuse the ViewModel with
the MVVM pattern.
The use of a view model can make the interaction between model and
view more simple. A model can sometimes be over complicated having
other model objects as members, which could have model objects as
member etc..
By using a view model you have a good way to simplify what the view
deals with. This will also filter down what can be seen in
intellisense, so if you have different people developing the models
than those working on the views, creating a simple view model can make
it much easier for those just dealing with the UI.
The simple and most common solution to this is to create a composite view model class. This can be a composed class (containing references to your domain models), or a flattened class, referencing properties from each class individually.
So you could do this:
public class HtmlItemViewModel
{
public ArticleItem ArticleItem {get; set;}
public NewsItem NewsItem {get; set;}
public EventItem EventItem {get; set;}
}
Or this:
public class HtmlItemViewModel
{
//Article Item Properties
public string ArticleTitle {get; set;}
public string ArticleContent {get; set;}
public string ArticleSummary {get; set;}
//News Item Properties
public string Headline {get; set;}
public DateTime PublishDate {get; set;}
public string NewsItemSummary {get; set;}
public string NewsItemContent {get; set;}
//Event Item Properties
public string EventTitle {get; set;}
public DateTime StartDate {get; set;}
public DateTime EndDate {get; set;}
public string EventContent {get; set;}
}
Then, whichever way you choose to construct the view model, you will map the view model properties to the domain model(s) in the controller. You can do this mapping manually
HtmlItemViewModel.ArticleTitle = ArticleItem.ArticleTitle;
//and so on...
Or you can use a third party tool like AutoMapper
I tend to favor the flattened view model in most scenarios as it allows me to only send the data I need, no more, no less. And it also allows me to put my data annotations for input validation on the view model instead of the domain model.

Entity framework code first - map class with List<> of another class to multiple tables?

I'm evaluating EF4 and have a pretty basic question...I think, that I can't seem to find an answer for..
take the following example:
public class Question
{
public string question {get;set;}
public string answer {get; set;}
}
public class Person
{
public string Id {get; set;}
public string Name {get; set;}
public List<Question> Questions {get; set;}
}
Then I have the following tables in the database
Person
(
id,
name
)
Question
(
id,
personId,
question,
answer,
)
Can I use the EF4 code first to map the Person class to the two tables, or do I ahve to restructure my POCO's first so the question class contains the id and personId - which is not something I would like to do.
Can I add something to the OnModelCreating to map the class as I need it to be mapped?
Thanks!
Ok here's what I've done for now - but it requires me having to restructure my question class...
public class Question
{
public int Id {get;set;} /* New */
public int PersonId {get;set;} /* New */
public string question {get;set;}
public string answer {get; set;}
public virtual Person PersonObj {get;set;}
}
public class Person
{
public string Id {get; set;}
public string Name {get; set;}
public List<Question> Questions {get; set;}
}
and added the following in the OnModelCreating event
modelBuilder.Entity<Person>().
HasMany(d => d.Questions).
WithRequired(c => c.Person).
HasForeignKey(c => c.PersonId).
WillCascadeOnDelete();
Not sure it's fully right...but seems to be working for now.

Resources