How to model this correctly in Entity Framework? - asp.net-core

I have a requirement that I am not sure how to accomplish, in my existing data I have a list of customers, each customer should be assigned a staffMember to work with them, so would this be a 1 to 1 relationship or a 1 to many relationship, having trouble wrapping my head around how to model the data, as I want to figure out how to model this correctly. Since a staff member can be assigned to many different customers How should I model this? Does this look correct?
What I would like is to have the form pull the list of staff members available from the staff table, when inputting a new customer, ideally by the name
which I figure I could probably do using linq..
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public string BusinessName { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public DateTime RequestDate { get; set; }
public Staff Staff { get; set; }
public List<CustomerJob> CustomerJobs { get; set; }
}
public class Staff
{
public int ID { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string EMail { get; set; }
public int CustomerId { get; set; }
}

Customer have exactly 1 Staff while a single Staff maybe assigned to more than 1 Customer. So this is a one-to-many relation.
It is better that Customer be aware of its Staff. It could be called AssignedStaff. Staff itslef does not need to have a property to show all its Csutomers. Tough you can extract Customer list of a Staff using a simple query.
My recommended class structure is as follow:
public class Customer
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string BusinessName { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public DateTime RequestDate { get; set; }
public Staff AssignedStaff { get; set; }
public List<CustomerJob> CustomerJobs { get; set; }
}
public class Staff
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string EMail { get; set; }
}
A query for extracting Customer list of a Staff:
var customers = _dbContext.Customers.Where(x => x.AssignedStaff.Id == staffId);

Related

Asp Core Multiple Entity Relationships

I am working on modeling a Contact Info Structure and haven't quite figured out how the relationships should be coded with EF Core. I am fairly new to using EF for data access layer.
I want to have a contact model which can contain Website, Phonenumbers, Emails, or Social Info. Then the contact info will be added to several different models. Any suggestions would be helpful, I am not sure how code this One to many with many table relationship or if it is even possible using EF.
Models so far
public class Contact
{
public String Id { get; set; }
public Int32 ContactType { get; set; } //Enum for Website, Phonenumbers, Emails, or Social
public String RecId { get; set; } //FK to multiple Models
public String RecType { get; set; }//Value for which model the RecID is for
public String Name { get; set; }
public String Value { get; set; }
}
public class ContactInfo
{
public virtual IList<Contact> Website { get; set; }
public virtual IList<Contact> PhoneNumbers { get; set; }
public virtual IList<Contact> Emails { get; set; }
public virtual IList<Contact> Socials { get; set; }
}
//Example of models to use the contact model
public class Company
{
....
pubic ContactInfo ContactInfo { get; set;}
}
public class Client
{
....
pubic ContactInfo ContactInfo { get; set;}
}
If I understand your question correctly, then you could use following code sample, but it is not exactly what you are trying to achieve. This may give you some understanding what you need to do with EF.
public class Contact
{
public String Id { get; set; }
public ContactType ContactType { get; set; } //Enum for Website, Phonenumbers, Emails, or Social
public String RecId { get; set; } //FK to multiple Models (This can't be the FK to multiple table as it should be FK for one table so that FK for Company would be CompanyId, FK for the Client should ClientId)
public String RecType { get; set; }//Value for which model the RecID is for (This need to rethink as it may not needed.)
public String Name { get; set; }
public String Value { get; set; }
// One to Many Relationship
public string CompanyId? { get; set; }
public string ClientId? { get; set; }
public Company Company { get; set; }
public Client Client { get; set; }
}
public class Company
{
public String Id { get; set; }
// Other properties
// One to Many Relationship
public ICollection<Contact> Contacts { get; set; }
}
public class Client
{
public String Id { get; set; }
// Other properties
// One to Many Relationship
public ICollection<Contact> Contacts { get; set; }
}
/* Db context */
public class YourDbContext : DbContext
{
public YourDbContext(DbContextOptions<YourDbContext> options)
: base(options)
{
}
public virtual DbSet<Contact> Contacts { get; set; }
public virtual DbSet<Company> Companies { get; set; }
public virtual DbSet<Client> Clients { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Contact>().HasKey(t => t.Id);
modelBuilder.Entity<Company>().HasKey(t => t.Id);
modelBuilder.Entity<Company>().HasMany(c => c.Contacts).WithOne(c => c.Company).HasForeignKey(k => k.CompanyId);
modelBuilder.Entity<Client>().HasKey(t => t.Id);
modelBuilder.Entity<Client>().HasMany(t => t.Contacts).WithOne(c =>c.Client).HasForeignKey(k => k.ClientId);
}
}
/* Db context - Endd */
public enum ContactType
{
Website,
PhoneNumbers,
Emails,
Social
}
Let me know if you need anymore information.
With the help from DSR, this is the solution I have (untested).
public class Company
{
public String Id { get; set; }
public String Name { get; set; }
public ICollection<ContactPhone> PhoneNumbers { get; set; }
public ICollection<ContactEmail> ContactEmail { get; set; }
public ICollection<ContactWebsite> ContactWebsite { get; set; }
public ICollection<ContactSocial> ContactSocial { get; set; }
}
public class Client
{
public String Id { get; set; }
public String Name { get; set; }
public ICollection<ContactPhone> PhoneNumbers { get; set; }
public ICollection<ContactEmail> ContactEmail { get; set; }
public ICollection<ContactWebsite> ContactWebsite { get; set; }
public ICollection<ContactSocial> ContactSocial { get; set; }
}
public class ContactWebsite
{
public String Id { get; set; }
public String Url { get; set; }
public Company Company { get; set; }
public Client Client { get; set; }
}
public class ContactPhone
{
public String Id { get; set; }
public String Type { get; set; }
public String Number { get; set; }
public Company Company { get; set; }
public Client Client { get; set; }
}
public class ContactEmail
{
public String Id { get; set; }
public String Category { get; set; }
public String Email { get; set; }
public Company Company { get; set; }
public Client Client { get; set; }
}
public class ContactSocial
{
public String Id { get; set; }
public String Site { get; set; }
public String Handle { get; set; }
public Company Company { get; set; }
public Client Client { get; set; }
}

Entity relationships code first approach

I am building Patient Appointment booking system and using the code first approach of the entity framework. I have designed the models and their relationships. Could somebody let me know if there is anything incorrect ?
I am assuming following are the relationships. Please correct me if I am wrong
One Patient can have many appointments and one appointment can belong to only one patient. Hence Patient has one to many relationship with appointments.
One Practioner can have many appointments and one appointment can belong to only one practioner. Hence Practioner has one to many relationship with appointments.
One Practioner can have many PractionerTypes(E.g Doctor,Nurse) and one PractionerType can belong to only one Practioner. Hence Practioner has one to many relationship with PractionerTypes.
One Appointment can have many AppointmentTypes(E.g Standard,Special) and one AppointmentTypes can belong to only one Appointment . Hence Appointment has one to many relationship with AppointmentTypes .
One Practioner can have many PractitionerAvailableHours and one PractitionerAvailableHours can belong to only one Practioner
I am bit confused after seeing this article http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx
As per this article, when you are doing a one to many relationship , you need to define the property of the many class in the one class and have a collection property of one class in the many class. In their example. Student is the one class and Standard is the many class. The student has virtual property method of the standard class and the standard class has the virtual collection property of the student class
In my design, Its just the other way round. Assuming Patient and Appointments have one to many relationship
Considering the above the enity design would look as follows
Appointment
public class Appointment
{
public int Id { get; set; }
public DateTime Date { get; set; }
public DateTime Time { get; set; }
public string Note { get; set; }
public virtual Patient Patient { get; set; }
public virtual Practioner Practioner { get; set; }
public int PatientId { get; set; }
public int PractionerId { get; set; }
public virtual ICollection<AppointmentType> AppointmentType { get; set; }
}
AppointmentType
public class AppointmentType
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Appointment Appointment { get; set; }
public int AppointmentId { get; set; }
}
Patient
public class Patient
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public char Gender { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postcode { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; }
}
Practioner
public class Practioner
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; }
public virtual ICollection<PractitionerAvailableHours> PractionerAvailableHours { get; set; }
}
PractionerType
public class PractionerType
{
public int Id { get; set; }
public string Name { get; set; }
public int PractionerId { get; set; }
public virtual Practioner Practioner { get; set; }
}
PractitionerAvailableHours
public class PractitionerAvailableHours
{
public int Id { get; set; }
public virtual Practioner Practioner { get; set; }
public int PractionerId { get; set; }
public DateTime AvailableDate { get; set; }
public int AvailableHours { get; set; }
}

not able to get subcategory of particular category in mvc 4 and designing issue of category and subcategory model class

i am working on help desk system in mvc.
i have only one master table for user and technicians.
this is my category class:
public class Category
{
[Key]
public int CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<SubCategory> subCategory { get; set; }//category can have more than 1 category
}
This is my Subcategory:
public class SubCategory
{
[Key]
public int SubcategoryId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public virtual ICollection<TicketInfo> ticketsInfo { get; set; }/to keep track of all tickets under this particular subcategory.
public virtual ICollection<UserDetails> technicianInfo { get; set; }//to keep track of technician and user under this subcategory.
public virtual Category category { get; set; }
}
This is my usermaster(it defines both user and technician)
public class UserDetails
{
public string UserName { get; set; }
[Key]
public int UserId { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public string PhoneNo { get; set; }
public string EmailId { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
public int SubcategoryId { get; set; }
public int AddressId { get; set; }
public Boolean IsActive { get; set; }
public DateTime CreatedDate { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual SubCategory subCategory { get; set; }
}
now when i am firing dis query::
public list<Category> FetchTicketDetailsforSubcategory(int categoryId)
{
using (HelpDeskdbContext context = new HelpDeskdbContext())
{
var category = from temp in context.Category where temp.CategoryId == categoryId select temp;
return category;
}
}
it just show me the category but not subcategory under that category.
it show me this on subcategory:The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
can any one figure out what is wrong with my class design??
try this
context.Category.Where(x=>x.CategoryId == categoryId).SelectMany(x=>x.subCategory).ToList()

How to create a history model of a specific model on MVC 4

I'm still new in creating Models using Entity Framework and MVC 4 Razor. I'm having a problem on how can I save a history of a model. How can I create a model that have a history on specific tables or fields ? For ex: If I wish to create a history on the changes on the school. Its still not clear to me how will I I create the model that saves history. How will be the triggering do I have to execute the save function on different models with the same data ?
Thank you so much in advance.
If anyone could be a simple example of model and a model history and how it is functioning, I'll be very grateful. Like a Sales or sales history.
Here's my code
One To Many
public class Child
{
[Key]
public int ChildID { get; set; }
[Required,Display(Name="Project Code")]
public string ProjectCode { get; set; }
public string Status { get; set; }
[DataType(DataType.Date)]
public DateTime StatusDate { get; set; }
public string FamilyName { get; set; }
public string GivenName { get; set; }
public string MiddleName { get; set; }
[DataType(DataType.Date)]
public DateTime Birthdate { get; set; }
public string Gender {get;set;}
public string Address { get; set; }
public string Section { get; set; }
public int SchoolLevelID { get; set; }
public int SchoolYearID { get; set; }
public int AreaID { get; set; }
public int SchoolID { get; set; }
public int GradeLevelID { get; set; }
//Foreign Key - One to Many
public virtual SchoolLevel SchoolLevel { get; set; }
public virtual SchoolYear SchoolYear { get; set; }
public virtual Area Area { get; set; }
public virtual School School { get; set; }
public virtual GradeLevel GradeLevel{get;set;}
//Child is foreign key at the table
public virtual ICollection<Guardian> Guardians { get; set; }
}
public class SchoolLevel
{
public int SchoolLevelID { get; set; }
public string SchoolLevelName { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class SchoolYear
{
public int SchoolYearID { get; set; }
public string SchoolYearName { get; set; }
public virtual ICollection<Child> Children{get;set;}
}
public class Area
{
public int AreaID{get;set;}
public string AreaName { get; set; }
public virtual ICollection<Child> Children{get;set;}
}
public class School
{
public int SchoolID { get; set; }
public string SchoolName{get;set;}
public virtual ICollection<Child> Children { get; set; }
}
public class GradeLevel
{
public int GradeLevelID{get;set;}
public string GradeLevelName { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class ChildDbContext : DbContext
{
public DbSet<Child> Children { get; set; }
public DbSet<SchoolLevel> SchoolLevels { get; set; }
public DbSet<SchoolYear> SchoolYears { get; set; }
public DbSet<Area> Areas { get; set; }
public DbSet<School> Schools { get; set; }
public DbSet<GradeLevel> GradeLevels { get; set; }
public DbSet<Guardian> Guardians { get; set; }
}
You can use this approach: Create a History model. That contains 1 changeness like o log.
public class History
{
public int HistoryId { get; set; }
public int ModelType { get; set; } //it is ModelTypeEnum value.
public int ModelId { get; set; }
public string PropertyName { get; set; }
public string Propertyvalue {get;set;}
public DateTime ChangeDate { get; set; }
public int ChangedUserId { get; set; }
}
And Enum:
public enum ModelTypeEnum
{
Child =1,
SchoolLevel = 2,
//etc..
};
For example, when you edit 1 Child entity, give changed properties name and value, it's id, type and others (ChangeDate, ChangedUserId) to History and save histories. If 3 properties will change you should save 3 history entities. Then, you can load (filter) histories by ModelId, by ChangedUserId etc.

Ouerying an object inside ravendb document

There is a doubt as of how to query or retrieve a value from an object stored in an document as follows in raven db.
class User
{
public String Id { get; set; }
public AccountType AccountType { get; set; }Servicetax
public String MainAccountMobileNo { get; set; }
public UserStatus Status { get; set; }
public String EmailId { get; set; }
public String DisplayName { get; set; }
public Object User { get; set; }
}
Here i am storing three different types of classes into the object User.
Say Customer,Retailer and Trader.
Customer
{
public String Name{ get; set; }
public String Address { get; set; }
public String MobileNo { get; set; }
public String EmailId { get; set; }
}
Retailer
{
public String Name{ get; set; }
public String Address { get; set; }
public String MobileNo { get; set; }
public String EmailId { get; set; }
}
Trader
{
public String Name{ get; set; }
public String Address { get; set; }
public String MobileNo { get; set; }
public String EmailId { get; set; }
}
Now is it possible to retrieve results based on the Customer's class detail?
That is now i want to retrieve All the Customers based on Address in the customer class, So how will i do it? How to typecast the object user in the query to type customer.
Thanks.
The user object in the document can store any type of class's object like account info trader in the above image. So how can i query from the object type that cannot is not definite and changing.
var Result = sess.Query<UserAccountInfo>().Where(x => x.AccountType == usertype && ((AccountInfoCustomer)x.User).Customerstatus == CustomerStatus.Pending);
This is the query that's been tried and this is the exception that's been caught
{"Url:
\"/indexes/dynamic/UserAccountInfos?query=AccountType%253ADistributor%2520AND%2520User).Customerstatus%253APending&start=0&pageSize=128&aggregation=None\"\r\n\r\nSystem.ArgumentException:
The field ')_Customerstatus' is not indexed, cannot query on fields
that are not indexed\r\n at
Raven.Database.Indexing.Index.IndexQueryOperation.AssertQueryDoesNotContainFieldsThatAreNotIndexes()
The problem here was the build of raven db. i was using the older build after changing it to newer version the query
var Result = sess.Query<UserAccountInfo>().Where(x => x.AccountType == usertype && ((AccountInfoCustomer)x.User).Customerstatus == CustomerStatus.Pending);
works fine.
Your classes are not very DRY. Consider this instead:
public abstract class Person
{
public string Name{ get; set; }
public string Address { get; set; }
public string MobileNumber { get; set; }
public string EmailAddress { get; set; }
}
public class Customer : Person {}
public class Retailer : Person {}
public class Trader : Person {}
Then, in your User class replace
public Object User { get; set; }
With this:
public Person Person { get; set; }
That way, you can store an instance of any of the 3 derived types. I wouldn't call the property User given that the containing class is called User and User.User could get confusing to anyone having to understand your code.