Well i've been tring for some time to make Many-to-Many relationship between three tables.
Forum, Role, AccessMask.
In SQL It would like this:
ForumID | RoleID | AccessMaskID
--------------------------------
1 | 1 | 2
2 | 2 | 1
And so on. You got the idea. ForumID and RoleID is primary key for table. Question is.. how to do it in DbContext ?
It alawys screaming that entity is missing key. (really ?). I found a way to make and many-to-many relationship between two tables with modelBuilder, but as you see I still will be missing one more table
This will not be many-to-many relationship. You must expose this table as separate entity and map three one-to-many relationships. Many-to-many relationship works only between two tables if junction table contains only keys of these tables.
public class Forum
{
public int Id { get; set; }
...
public virtual ICollection<ForumRole> ForumRoles { get; set; }
}
public class Role
{
public int Id { get; set; }
...
public virtual ICollection<ForumRole> ForumRoles { get; set; }
}
public class AccessMask
{
public int Id { get; set; }
...
public virtual ICollection<ForumRole> ForumRoles { get; set; }
}
public class ForumRole
{
[Key, Column(Order = 0)]
public int ForumId { get; set; }
[Key, Column(Order = 1)]
public int RoleId { get; set; }
public int AccessMaskId { get; set; }
public virtual Forum Forum { get; set; }
public virtual Role Role { get; set; }
public virtual AccessMask AccssMask { get; set; }
}
Related
I have created 3 tables using Code First Approach. I get the following Model Validation Exception when i execute a Find on student table.
Student_courses_Target_Student_courses_Source: : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical.
public class University
{
[Key]
public string Uni_ID { get; set; }
public virtual List<Course> Courses { get; set; }
}
public class Course
{
[Key]
[Column(Order = 1)]
public string Course_ID { get; set; }
[Key,ForeignKey("uni")]
[Column(Order = 2)]
public string Uni_ID { get; set; }
public virtual ICollection<Student> Students { get; set; }
public virtual University uni { get; set; }
}
public class Student
{
[Key,ForeignKey("course"), Column(Order = 1)]
public string Course_ID { get; set; }
[ForeignKey("course"),Column(Order = 2)]
public string Uni_ID { get; set; }
[Key]
[Column(Order = 3)]
public string Student_ID { get; set; }
public virtual Course course { get; set; }
}
By my understanding , the exception means that i have not mapped my foreign keys in student table to the primary keys in course table. But i have done it . Is there an issue as to how the 'Uni_ID' occurs as Primary key in both University and Course Tables and perhaps i have gone wrong in referencing it as foreign key in the Student table ?
I have some entities that can be associated with each other. A simple pair of classes to do this would ideally look like:
public class linkableEntity
{
public int Id { get; set;}
public virtual ICollection<Link> Links { get; set; }
}
public class Link
{
public int Id { get; set; }
public int SomeProperty { get; set; }
public int entity1Id { get; set; }
public virtual LinkableEntity entity1 { get; set;}
public int entity2Id { get; set; }
public virtual LinkableEntity entity2 { get; set;}
}
With tables something like:
Table linkableEntity
Column Id
Table link
Column entityId1 - foreign key to linkableEntity.Id
Column entityId2 - foreign key to linkableEntity.Id
Column someProperty
Having tried this out, and looking at this question: Entity Framework Code First - two Foreign Keys from same table I don't think that what I want to do was possible in EF4, has anything changed in EF6 that would make this possible? (I haven't found any more recent questions addressing this subject)
If not, is there a better way of representing this than changing linkableEntity to something like:
public class linkableEntity
{
public int Id { get; set;}
public virtual ICollection<Link> LinksWhereFirst { get; set; }
public virtual ICollection<Link> LinksWhereSecond { get; set; }
}
and then dealing with the mess?
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.
I have two database tables:
Customers
CustomerId (PK)
Name
...
CustomerSettings
CustomerId (PK)
Setting1
Setting2
...
Is it possible to have these classes using code-first? If so, what is the fluent mapping?
public class Customer
{
public int CustomerId { get; set; }
public int Name { get; set; }
public CustomerSetting CustomerSetting { get; set; }
}
public class CustomerSetting
{
public int CustomerId { get; set; }
public int Setting1 { get; set; }
public int Setting2 { get; set; }
public Customer Customer { get; set; }
}
I personally don't like one-to-one tables. After all, why not just add the setting columns to the customer table? Unfortunately, this is what I need to develop against. I can't figure the correct code-first mappings for such a scenario. Thanks for your help.
If you are going for code first and want to have both Customer And CustomerSettings classes,
but only a single table for both, as your post suggests ,
I would use complex types.
see a good example here:
http://weblogs.asp.net/manavi/archive/2010/12/11/entity-association-mapping-with-code-first-part-1-one-to-one-associations.aspx
So , your object model should look like this (I've not tested it):
public class Customer
{
public Customer()
{
CustomerSetting= new CustomerSetting();
}
public int CustomerId { get; set; }
public int Name { get; set; }
public CustomerSetting CustomerSetting { get; set; }
}
[ComplexType]
public class CustomerSetting
{
public int CustomerId { get; set; }
public int Setting1 { get; set; }
public int Setting2 { get; set; }
public Customer Customer { get; set; }
}
Your model classess are correct, if you want you can add this to your model builder to specify which table is the "main one":
.Entity<Customer>()
.HasOptional(c => c.CustomerSetting)
.WithRequired(u => u.Customer);
Person and EHR(electronic health record) are one to one related.
Person has EHRId nullable and EHR has PersonId not nullable.
At the same time EHR and Person must be many to many related.
Because a person can have many medics (represented by person entity) and a medic can have many EHRs.
I would like to have extra attributes on the join table.
I dont know how to define this in EF.
Please help.
Here are my classes.
public class Person
{
public int ID { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public ICollection<UserSpecialist> patients { get; set; }
public int ehrID { get; set; }
public virtual EHR ehr { get; set; }
}
public class EHR
{
public int ID { get; set; }
public bool asthmatic{ get; set; }
public ICollection<UserSpecialist> specialists { get; set; }
public int PersonID { get; set; }
public virtual Person Person { get; set; }
}
public class UserSpecialist
{
public int ID { get; set; }
public DateTime creationDate { get; set; }
public int PersonID { get; set; }
public int EHRID { get; set; }
public virtual Person Person { get; set; }
public virtual EHR EHR { get; set; }
}
When EF tries to create the database throws this error
Unable to determine the principal end
of an association between the types
'Project.Person' and 'Project.EHR'.
The principal end of this association
must be explicitly configured using
either the relationship fluent API or
data annotations.
Please help
Person and EHR are not one-to-one related and they cannot be in EF. What you have defined is bidirectional one-to-many. You have also declared both relations as required because FK's are not nullable.
Real one-to-one can be defined in EF only if EHR's PK (Id) is also FK to Person. Once you define this the part with many-to-many becomes really strange because Person will be related with EHRs of other persons. You domain description is most probably not correct.