I want to have one table with pictures for many other objects, lets say for Meals, Ingridents, ...
One Picture is for particular class (say Meal). This way I could have many tables with PictureId as FK, but can't apply this 2nd data annotation attribute.
public class Picture
{
[Key, ForeignKey("Ingridient"), ForeignKey("Meal")] //<---here I get error
public int PictureId { get; set; }
//properties
public byte[] PictureData { get; set; }
public string Name { get; set; }
[Required]
public virtual Ingridient Ingridient { get; set; } //1 - 1
[Required]
public virtual Meal Meal { get; set; } //1 - 1
}
I think I don't follow convention but please tell me how to fix it.
Why PictureId can't be a FK in many tables (Meals, Ingridients, ...)
I could have many tables with PictureId as FK
Then those other Entities should have the Foreign Key properties and Navigation Properties.
eg
public class Meal
{
public int MealId {get;set;}
// ...
public int? PictureId {get;set;}
public virtual Picture Picture {get;set;}
}
Related
I have two tables: Place, and MenuSection, that currently have a one-to-many relationship defined like so:
public class Place
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int PlaceID { get; set; }
public virtual ICollection<MenuSection> MenuSections { get; set; }
}
public class MenuSection
{
[Key]
public int MenuSectionID { get; set; }
public int PlaceID { get; set; }
}
However, I now need a many-to-many relationship. If I was just starting out then this would be achieved by changing the MenuSection class to look like this:
public class MenuSection
{
[Key]
public int MenuSectionID { get; set; }
public virtual ICollection<Place> Places { get; set; }
}
The problem is I already have vast amounts of data and business logic associated with the current relationship. So I figure I'll have to leave the PlaceID property in for now and add the places collection.
My question then is: how do I then tell EF the relationship is now many-to-many and to populate the auto-generated joining table with the existing relationships so that I can then remove the PlaceID property from the MenuSection class?
Alternatively I suppose I could manually create a joining table and rewrite all the business logic, manually move the existing relationships over and rewrite all the business logic like so:
public class Place
{
[Key]
[ForeignKey("Place")]
public int PlaceID { get; set; }
[Key]
[ForeignKey("MenuSection")]
public int MenuSectionID { get; set; }
public virtual Place Place { get; set; }
public virtual MenuSection MenuSection { get; set; }
}
I'm surprised this question hasn't been asked before so I just wanted to check I haven't missed a trick?
I have a model class:
public class UserProfile
{
public string UserID { get; set; }
public string Name{ get; set; }
public ICollection<AddressMaster> AddressMaster { get; set; }
}
The above class have a 1 to many relationship with AddressMaster model class given below:
public class AddressMaster
{
public string AddrID{ get; set; }
public string AddressLine1{ get; set; }
public UserProfile UserProfile { get; set; }
public TheatreLocation TheatreLocation { get; set; }
}
The problem is, there is one other model also that has a 1 to many relationship with addressmaster, which is:
public class TheatreLocation
{
public string LocationID { get; set; }
public string Name{ get; set; }
public ICollection<AddressMaster> AddressMaster { get; set; }
}
So instead of having foreign key at the addressmaster, how can we have a intermediate table between addressmaster and the userprofile & another such table b/w addressmaster and theatre?
Or am i getting the whole concept wrong?
Thanks.
So instead of having foreign key at the addressmaster, how can we have
a intermediate table between addressmaster and the userprofile &
another such table b/w addressmaster and theatre?
If you do not want to set any foreign key and add a intermediate table.Design like below:
public class UserProfile
{
[Key]
public string UserID { get; set; }
public string Name { get; set; }
}
public class AddressMaster
{
[Key]
public string AddrID { get; set; }
public string AddressLine1 { get; set; }
}
public class UserAddress
{
[Key]
public string AddrID { get; set; }
public string UserID { get; set; }
}
Add the primary key to the intermediate table UserAddress.The AddrId could only has one value,but the UserID could have many value which is like one-to-many relationship.
Or am i getting the whole concept wrong?
Nothing wrong.Using navigation property like what you did is also good.
Your table definitions would probably wind up something like this:
UserProfile
UserId PK
Theather
TheatreId PK
Address
AddrID PK
AddressLine1
UserAddress
UserId PK & FK
AddressId FK
TheatreAddress
TheatreID PK & FK
AddressId FK
This is just good normalisation - i.e. you have a generic 'address' table in the database. Several entities may have an address and have either one-many or many-many relationships with addresses, but a specific address only needs to be recorded once.
The PK on the intermediate table only on the UserId (for example) ensures that this is one-many and not many-many.
When I have two models with one to many relationship, they look like the models below:
public class Student
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int StudentID { get; set; }
public string Name { get; set; }
public int ClassID { get; set; }
[ForeignKey("ClassID")]
public virtual Class Class { get; set; }
}
public class Class
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ClassID { get; set; }
public string Name { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
This means that I can use the include method to get the related data. Now I work on a project with more than 600 tables. For these tables there are no relationships and I can not create relationships between the tables. Is there a way to link the models somehow so that I will be able to get the related data?
Yes, you can join tables without Relationships in Model Classes.
For example assume you have TeacherId in both of your tables Student and Class
You can join two tables based on TeacherId as follows
DbContext.Students
.Join(DbContext.Classes,student=>student.TeacherId,class=>class.TeacherId, (std,tchr)=> new {std,tchr});
I have an annoying problem that i can't seem to solve. Lets say i have a database with two tables.
Student
INT Id
NVARCHAR(30) Name
INT PrimaryTeacherId
INT SecondaryTeacherId
Teacher
INT Id
NVARCHAR(30) Name
Now when i set foreign key for PrimaryTeacherId and SecondaryTeacherId and use DatabaseFirst mapping in my project i get something like this for Student table
public partial class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int PrimaryTeacherId { get; set; }
public int SecondaryTeacherId { get; set; }
public virtual Teacher Teacher { get; set; }
public virtual Teacher Teacher1 { get; set; }
}
Note the virtual part of the class and their names, Teacher and Teacher1. No matter how i call my FKs entity framework will just override it and set increment names. That's ok if i have one or two keys to the same table but when there is more it's easy to get lost and code looks kinda annoying having object names with numbers in them. I know i can change generated classes name in my solution but when i update model changes will be lost. I'm also using Metadata partial classes for generated classes (mostly for validation and display attributes), can i change name there maybe?
TLDR: I would like to have Teacher and Teacher1 have custom names, so something like this would be awesome
public partial class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int PrimaryTeacherId { get; set; }
public int SecondaryTeacherId { get; set; }
public virtual Teacher PrimaryTeacher { get; set; }
public virtual Teacher SecondaryTeacher { get; set; }
}
I've the following situation I try to solve : I've 2 tables, a Course table with some fields and a CourseDescription table which is optional (so Course may have a CourseDescription but CourseDescription must have a Course). I'm trying to set this up. So far, here's what I have :
public class Course
{
[Key, Column("Key_Course")]
public int ID { get; set; }
public string Name { get; set; }
public virtual CourseDescription CourseDescription { get; set; }
}
public class CourseDescription
{
[Key, ForeignKey("Course")]
public int ID { get; set; }
public string Description { get; set; }
public string PreRequis { get; set; }
public int CoursesID { get; set; }
[ForeignKey("CoursesID")]
public Course Course { get; set; }
}
This "works" meaning that EF doesn't complains about my model but the relation is not properly done because EF associate the PK of CourseDescription with the PK of Course. In my database, this is not the case (ex : CourseDescription.ID=1 is associated with CourseDescription.CoursesID=3, not 1).
Is there a way to fix that with data annotation ? I know I can use the fluent API but I don't want to override the model building just for that (unless there's no other way).
Thanks
Well, I think you have two choices:
Configure an one to many relationship
If you want to map the FK of the relationship between Course and CourseDescription, and you don't want to declare that FK property as Key of the CourseDescription entity, then, you don't have other choice that configure an one-to-many relationship. In that case your model would be like this:
public class Course
{
[Key, Column("Key_Course")]
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<CourseDescription> CourseDescriptions { get; set;}
}
public class CourseDescription
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
public string PreRequis { get; set; }
[ForeignKey("Course")]
public int CourseID { get; set; }
public Course Course { get; set; }
}
Configure an one-to-one relationship but not map the FK of the
relationship
The only way that EF lets you map the FK in an one-to-one relationship is when the FK is declared as a PK too, so if you want to have diferent Ids in both entities and you want to stablish an one-to-one relationship, then you could do something like this:
public class Course
{
[Key, Column("Key_Course")]
public int ID { get; set; }
public string Name { get; set; }
public CourseDescription CourseDescription { get; set;}
}
public class CourseDescription
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
public string PreRequis { get; set; }
[Required]
public Course Course { get; set; }
}
And work with the navigations properties.
It looks like you should not use ForeignKey attribute for ID property of CourseDescription class as you don't want to have an association between primary keys. Try to remove it.
Edit: It looks like I misunderstood the question previous time.
You can have your CourseDescription this way.
public class CourseDescription
{
[Key, ForeignKey("Course")]
public int ID { get; set; }
public string Description { get; set; }
public string PreRequis { get; set; }
public Course Course { get; set; }
}
In this case you don't need to have CoursesID field. Entities will be connected by primary keys.