Can use interfaces in creating my models in Entity Framework Codefirst? - c#

I'm new to Entity Framework and I'm practicing CodeFirst. My problem is I'm creating a model class and I want that class to inherit from two other classes. For example, an Employee has personal information such as first name,middle name,last name, and etc... it has also a contact information such as address,phone,email, and etc... Students also has those properties as well. The reason why I separated those information into two different classes was that, another entity also can have contact information but without personal information, such as a company,schools,hospitals,warehouses and etc...
Sample codes:
public class ContactInfo
{
public string Address { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
public class PersonalInfo
{
public string Firstname { get; set; }
public string Middlename { get; set; }
public string Lastname { get; set; }
}
public class Employee : // This should be inheriting from PersonalInfo and ContactInfo
{
public int EmployeeID { get; set; }
}
public class Supplier : ContactInfo // Inheriting from ContactInfo and no PersonalInfo
{
public int SupplierID { get; set; }
public string Name { get; set; }
}
What I wanted to do is to create interfaces (IPersonalInfo,IContactInfo) to be inherited by Employee so that it will look like this:
public class Employee : IPersonalInfo,IContactInfo
{
public int EmployeeID { get; set; }
}
Is this a good practice? And if not, how can I manage with this kind of scenario?

First of all, it sounds like you are confusing inheritance and composition. An example of inheritance would be having a common Person base class from which you could inherit an Employee or a Student. An example of composition would be an Employee and a Supplier each composed with a common ContactInfo object, but having no common base class.
When you design your entities, you are really designing the table structure of the underlying relational database. You can model inheritance: a common base class can be represented by its own table and any common fields, and any specialized classes could be in their own table with a foreign key linking to the common table. It may or may not make sense to do this - by breaking things up into separate tables, you're adding another join to your queries. This will slow down performance.
Composition can also be represented in a relational database, but it only really makes sense if it is a common component shared amongst many other data entities. ContactInfo is almost always going to be unique for a given person/supplier, so it really doesn't make sense to break it out into a separate table - you're just adding an extra table join which, again, will slow down performance on your queries.
You should think about moving inheritance/composition up a layer in your design. The entities (data access layer) should match the relational database, but the domain model (i.e. business objects layer) should adhere to object-oriented principles.

Ys, You have to define the inheritance in the model. After that make sure you define one/many to one/many relationship. Refer link here, good tutorial.
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application

Related

Mapping results of the repositories to the AGGREGATION ENTITY in DOMAIN layer

I'm working in a project with .NET core 3 and C# as language.
I'm trying to use Clean Architecture approach, CQRS and Repository Patterns. I chose DAPPER as ORM.
I have 3 layers:
DOMAIN : with my entities, aggregation entities, value object;
APPLICATION : here I'm implementing the logic with QUERIES and COMMAND (CQRS) and interface (for example repositories) that I'll implement in PERSISTENCE layer;
PERSISTENCE : with DAPPER, this layer share the same entities of the DOMAIN.
I have doubt about how to create aggregation entity. For example:
Class Person is an aggregation and a Person can have 1 to NPhoto
public class Person
{
public Person()
{
Photos = new HashSet<PersonHasPhotos>();
}
public int Id { get; set;}
public string Name { get; set;}
public ICollection<PersonHasPhotos> Photos { get; set; }
}
Class Photo is normal entity
public class Photo
{
public Photo()
{
}
public int Id { get; set;}
public string Description { get; set;}
public byte[] Photo { get; set;}
}
Class PersonHasPhotos that specify where (the position in the screen) the Person wants to see the photo in his HOME PAGE
public class PersonHasPhotos
{
public PersonHasPhotos()
{
}
public int PersonId { get; set;}
public int PhotoId { get; set;}
public string PositionOnTheScreen { get; set;}
public Photo Photo { get; set;}
public Person Person { get; set;}
}
In my APPLICATION layer I defined one REPOSITORY for each entity. Each repository has simple job specific for the entity (only simple CRUD, without JOIN). I chose this because I'll use repositories in APPLICATION layer and there I can put logic and also manage transactions.
I have IPersonRepository, IPhotoRepository and IPersonHasPhotoRepository.
public interface IPersonHasPhotosRepository
{
IEnumerable<PersonHasPhotos> GetForPerson(int PersonId);
}
public interface IPhotosRepository
{
IEnumerable<Photos> Get(int PersonId);
}
public interface IPersonRepository
{
Person Get(int PersonId);
}
In my APPLICATION layer I have a QUERY named GetPerson(int id). In the HANDLER of this query I call these repositories.
In my PERSISTENCE layer with DAPPER I can map the results of the query directly to my entity.
The domain entities are shared in all layers and I don't want to put logic in PERSISTENCE layer to explain how to create aggregation entity.
The problem is that these repositories give to me 3 different objects (Person, List<PersonHasPhoto>, List<Photo>) but I would like to merge them in only one object PERSON with its properties enhanced with the others objects.
What should I do? Where am I doing wrong?
I see two options
live with the fact that those three repositories return different entities (instances) and "link" and compare them based on their IDs
go for "Unit of work" pattern and have one repository returning always all three entities combined

Determining Entities and Value Objects in Domain Driven Design in a real project

This is for the first time I am implementing the concept of Domain Driven Design in a real project. The project is about generating a permit for employees which would enable them to enter company premises. Through an Intranet site, an employee who already possesses an Employee ID, will be able to apply for a permit or apply for replacement of a permit, in case the permit is damaged or lost. And an administrator will process the applications and hand over a physical permit in the end.
I have a couple of entities - User, Permit and one Value Object - Employee.
A User can be entirely identified by an Employee. Should I create a UserId as well? How do I handle the case in which the administrator may not only approve, but raise an application on behalf of an employee as well?
The Value Object Employee has an Id property EmployeeId which I know goes against the principle of a Value Object. However, in my case, Employee is read-only. It doesn't matter to me if I get only the EmployeeId or the Employee as a whole. Am I doing this right?
The Permit entity contains a lot of properties. How do I break down the properties of Permit into Value Objects?
public class User : Entity
{
public Employee Employee { get; set; }
public bool IsAdmin { get; set; }
}
public class Permit: Entity
{
public int ApplicationId { get; set; }
public string EmployeeId { get; set; }
public string Type { get; set; }
public string Status { get; set; }
public DateTime RequestDate { get; set; }
public DateTime IssuanceDate { get; set; }
public string IssuanceReason { get; set; }
public string SurrenderReason { get; set; }
}
public sealed class Employee : ValueObject<Employee>
{
public string EmployeeId { get; private set; }
public string Name { get; private set; }
public string Department { get; private set; }
public string Division { get; private set; }
public string BirthDate { get; private set; }
public string Designation { get; private set; }
public string BloodGroup { get; private set; }
public string SecurityLevel { get; private set; }
public string EmploymentDate { get; private set; }
}
Apart from the concerns, I'd be grateful if someone could guide me to go about it in the most appropriate manner possible. Thanks.
In modeling business processes, it will often help to think about the paperwork, rather than the things in the real world. The process begins when somebody files a request document, it ends when the adminstrator files an approval or a rejection, and so on. The domain model's job is to do the bookkeeping, and to perform some of the logic on behalf of the business.
See
Rinat Abdullin: Evolving a Process Manager...
Greg Young: Stop Over Engineering
Should I create a UserId as well?
If you need to handle the case where the person submitting the request is different from the person the permit is assigned to, then you should absolutely treat those as different values.
It doesn't matter to me if I get only the EmployeeId or the Employee as a whole. Am I doing this right?
Yes - there is nothing wrong with an immutable value having an identifier.
In more sophisticated models, value objects will often be composed from other value objects. For example, event though EmployeeId and BloodGroup are opaque character sequences, it's probably not OK to pass a blood group to a method that is expecting an employee id, or vice versa. So rather than leaving things "stringly typed", we might invest more work in the model to make those concepts explicit.
How do I break down the properties of Permit into Value Objects?
Again, values can be composed from other values. If there is a subset of cohesive properties, group them together.
Scott Wlaschin's Domain Modeling Made Functional is a great reference here.
Part of the point of "objects" is that we should be able to change the in memory data structures and still have everything "work". So you shouldn't feel like you are committed to a particular in memory layout.
(Note: it's really easily to couple your in memory layout to your persistent storage -- that will make things harder to change later; so try not to fall into that trap more than once.)
From my point of perspective it would be better to discard the User class, as it closely resembles the Employee class.
The property IsAdmin is a very hard constraint, from a broader perspective you could create an Enum that represents security groups. This enables you to implement security for certain areas where given group X has access and group Y does not. This could replace the string SecurityLevel in the Employee class. You could also implement these security groups in the Permit class.
The Permit class should be used by the Employee class. A user can have multiple permits, active and non-active. A boolean value defining that logic should be implemented into the Permit class. By implementing the active/non-active boolean in the Permit class, you could revoke access by simply switching the value of the boolean.

Which entity design for hierarchy tree in asp.net mvc-application

I just can't decide on which approach to choose to be able to have a hierarchial tree with partially different object types. The application is Asp.Net MVC and I'm using entity framework code first. My hierarchial tree is an information content structure. Each node in the tree can be of either one of my three implemented types.
For now, Table-per-type (TPT) seems to be my best choice of design but what do you think? Any drawbacks with my choice of design? Should the base class have a discriminator field, for example?
To illustrate, below's an pseudo example of my current design.
Regards, Clas Ericson
public abstract class PageObject
{
public int ID { get; set; }
public int? ParentID { get; set; }
public string Title { get; set; }
public virtual PageObject Parent { get; set; }
public virtual ICollection<PageObject> Children { get; set; }
}
[Table("LinkPage")]
public class LinkPage : PageObject
{
public string Url { get; set; }
}
[Table("FramedPage")]
public class FramedPage : LinkPage
{
public int? MinHeight { get; set; }
public int? MinWidth { get; set; }
}
[Table("ContentPage")]
public class ContentPage : PageObject
{
[DataType(DataType.Html)]
[AllowHtml]
public string Content { get; set; }
}
public class InheritanceMappingContext : DbContext
{
public DbSet<PageObject> PageObjects { get; set; }
}
Should the base class have a discriminator field, for example?
You don't have to declare it explicitly while using any of these approaches. Discriminator field will be automatically added as a table field by Entity Framework when using TPH approach, because it stores everything in 1 table, and this field acts like an pointer to which class this record belongs.
For now, Table-per-type (TPT) seems to be my best choice of design but
what do you think?
You should realize, that this is completely opinion-based question, moreover it depends on your needs. Each approach has it's advantages and vice versa.
TPH will grant you best performance, because all the data is selected by 1 query without any JOINS, but it requires properties in subclasses to be Nullable in the Database. Also TPH violates the third normal form (price for performance)
The primary advantage of TPT strategy is that the SQL schema is normalized but performance can be unacceptable for complex class hierarchies because queries always require a join across many tables
http://www.entityframeworktutorial.net/code-first/inheritance-strategy-in-code-first.aspx

MVC Architechture - models and entities

In order to make my web-application project I used some tutorials and downloaded 2 sample projects. I noticed that in both of them entities were imported from the SQL server into the project AND models were created for each related class. From what I understand, the entities represent the database itself while the models are the ones to check validations (for example) and after validations successfully passed, the data is sent in to the entities which in turn get it into the database (?) .
In my project I have no models at all. I thought that the entities represent the models, therefore why shall I create duplicate classes (rather entities and models which both look alike).
All the data annotations are inside the entities classes.
I was told that each change done in the tables inside the SQL server would erase my entire work.
I would like to know whether it's true or not, as well as why do I acctually need models when I have entities instead.
If models ARE needed, how do you acctually pass their data into the entities?
Edit:
I found this post Difference between model and entity which answers most of my question.
I would like to know whether my entire entity class's annotations are erased whenever I change a simple thing in the SQL server.
Why wouldn't the model class be an exact duplicate of the entity class (besides the data annotations)?
The models represents the database entities. Those models shouldn't be responsible for displaying data in views or validating user input - their only usage is to represent some table in a database as a c# object.
Let say you have model:
[Table("Products", Schema = "product")]
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
public long CategoryId { get; set; }
public string Description { get; set; }
public string ManufacturerUrl { get; set; }
public string ImageUrl { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
public Category Category { get; set; }
}
Now to make use of it in your views and add some validation if you like then you should create a so called ViewModel for it which could be something like this:
public class ProductViewModel
{
public long Id { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[DataType(DataType.Url)]
[Display(Name = "Producer")]
public string ManufacturerUrl { get; set; }
[DataType(DataType.ImageUrl)]
public string ImageUrl { get; set; }
[DataType(DataType.Currency)]
public decimal Price { get; set; }
[Display(Name = "In stock")]
public int Stock { get; set; }
public CategoryViewModel Category { get; set; }
}
Suppose your entity is Person. You decide to have the Entity as the Model, instead of a different class.
In your view (editing an existing person), there is a dropdownlist with country names (Person needs a Country entity). So, that means that you need a list of all possible countries, so the user can select one.
How do you pass that list of countries?
Well, if you have a separate class that you use as the Model, you can easily add a new property, put the list of countries in that, and then get that from your view.
So your viewmodel for this example would be:
public class PersonEditModel
{
public Person PersonToEdit { get; set; } //This is your entity from before
public List<Country> Countries { get; set; } //Extra data for the view
}
Think of your model as a sort of 'package' that combines your entity with all other needed information that the view requires. In case there is no extra information required, you could forego the Model and keep using the Entity directly.
But most people label this bad practice. What if you need an extra bit of information suddenly? You'd have to rewrite your code to now start implementing a model.
Long story short: If you have no need for extra data in the view, and you're working on a private project; do whatever you think is best. Professionally, I would suggest always using a Model, if only to make sure you can add extra data in the future.
Because as you rightly pointed out, your entities will be erased and recreated if you ever refreshed your edmx file.
You could actually lose the model layer if you use partial classes and put your business rules in there, but the point of having a model layer is that it is much simpler to write unit tests for models than for entities.
I suggest that after you've finished learning the basics, you go on and learn about Domain Driven Development (DDD) and Test Driven Development(TDD). All you questions will be answered then, because if I bombard you with all of the theory now you'd probably get lost or think it's much more difficult than it actually is..

C# ef inheritance

Considering OOP it should not be possible but considerring EF and the way of inheritance works on a DB level, i am wondering if EF allows to jave to child class objects inherit from the same object at the same time.
I mean.... Lets consider i have a table named person as the parrent table and have two tables that inherit from it named user and another named enployee.
Since the inheritance mapping works in EF works by tracking the same primary key in the child table and parrent table, it should be possible to have the person class and be able to cast it either to the employee or user class.
I suposse that some modifications would have to be made to the EF generated code.
If polymorphism is a must then you need to use table per type (TPT) or table per hierarchy (TPH) inheritance. Use TPH for domain models with a lot tables and TPT when there are less tables as queries can become messy the larger a domain model is.
TPT represents the is a part of a relationship. A user is a person and a user is an employee. Going on what you've said in your question, you could use TPT like so:
public abstract class Person
{
public int PersonId { get; set; } // EF will set this as PK
public string FirstName { get; set; }
public string LastName { get; set; }
}
[Table("User")]
public class User : Person
{
public string SomeUserProperty { get; set; }
}
[Table("Employee")]
public class Employee : Person
{
public string SomeEmployeeProperty { get; set; }
}
Then in your Context class you only create one DbSet which is of type base class:
public class MyDbContext: DbContext
{
public DbSet<Person> Person { get; set; }
}
Then in some part of you application where you want to create instances of User or Employee:
using (var db = new MyDbContext())
{
var user = db.Person.Create<User>();
user.SomeUserProperty = "I'm a user";
var emp = db.Person.Create<Employee>();
emp.SomeEmployeeProperty = "I'm an employee";
db.Person.Add(user);
db.Person.Add(emp);
db.SaveChanges();
}

Categories

Resources