How to have intermediate table for a 1 to many relationship? - entity-framework

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.

Related

Entity Frameworks Creates Auto Column

I am having a problem in Entity Framework. Entity Framework is generating auto column in sql-server and I am not geting how to make insert operation in that particuler column.
For Example in Teacher class,
public class Teacher
{
[Key]
public String Email { set; get; }
public String Name { set; get; }
public List<TeacherBasicInformation> Teacher_Basic_Information { set; get; } = new List<TeacherBasicInformation>();
public String Password { set; get; }
public List<Course> course { set; get; } = new List<Course>();
[JsonIgnore]
public String JWT_Token { set; get; }
[NotMapped]
[Compare("Password")]
public String ConfrimPassword { set; get; }
}
And in TeacherBasicInformation class ,
public class TeacherBasicInformation
{
[Key]
public int ID { set; get; }
[Required]
[MaxLength(20)]
public String Phone { set; get; }
[Required]
[MaxLength(100)]
public String Address { set; get; }
}
After the migration in the sql server, in TeacherBasicInformation table a auto column is created named 'TeacherEmail'. How Can I insert data into this column using form in asp.net core.
In order to prevent auto-generated columns for FK, use [ForeignKey("YourForeignKey")] on the related table in the entity class:
public int TeacherId { get; set; }
[ForeignKey("TeacherId")]
public virtual Teacher Teacher { get; set; }
It looks like you have the email column set up as the primary key column in your Teacher class, and the related database column. If that's the case, you're going to have trouble with it as it will need to be unique to that record, and primary keys aren't designed to be changed. It can be done in certain scenarios but isn't a best practice.
Perhaps a better approach is to have the [Key] attribute on a property of public int Id { get; set; } so they primary key is now a discrete number instead of an email address. Then you can access, set, and update the email address on each record, without interfering with the key at all.

Entity framework code first cant create primary and foreign key relationship

I am trying to create a relationship between two tables but keep getting the following error:
The ForeignKeyAttribute on property 'CallLogId' on type
'Ylp.Web.ParkingApi.DataLayer.Entities.ApiCallLogDetailEntity' is not
valid. The navigation property 'ApiCallLog' was not found on the
dependent type
'Ylp.Web.ParkingApi.DataLayer.Entities.ApiCallLogDetailEntity'. The
Name value should be a valid navigation property name.
DbContextMapping:
modelBuilder.Entity<ApiCallLogDetailEntity>()
.HasRequired<ApiCallLogEntity>(p => p.ApiCallLog);
Primary table:
[Table("ApiCallLog")]
public class ApiCallLogEntity
{
[Key, Column(Order = 0)]
public string CallLogId { get; set; }
[Key, Column(Order = 1)]
public string UserId { get; set; }
[Required]
public string CallFilterId { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
[Required]
public int Count { get; set; }
public virtual ICollection<ApiCallLogDetailEntity> Details { get; set; }
}
foreign table:
[Table("ApiCallLogDetail")]
public class ApiCallLogDetailEntity
{
[ForeignKey("ApiCallLog")]
public string CallLogId { get; set; }
[Required]
public string PrametersHashCode { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
public ApiCallLogEntity ApiCallLog { get;}
}
The foreign key must refer to the whole primary key of the parent table. In your parent table you have a composite primary key which includes CallLogId and UserId. The message is confusing, but this can be part of the error. Is it really necessary to include the UserId in the PK?
Another error is that you have not defined the PK in the dependent table. If the UserId is also necessary on the PK, include it in the dependent table, and make it part of the FK.

EF Code first : set optional one to one relationship with data annotation

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.

Creating a foreign key for complex type using EF 4.1 code first fluent-api

Below are my domain entities
public class User
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public DateTime? DateOfBirth { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public RoleType RoleType { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
}
I have made RoleType as a complex type (to acheive enum mapping). So I could use something like context.Users.FirstOrDefault(u => u.RoleType.Value == (long)RoleTypes.Admin)
RoleTypes.Admin is an enum mapping to the Role entity
public class RoleType
{
public int Value { get; set; }
// And all the implicit operators to map with enum
}
And then I have created a mapping using fluent api
public class RoleTypeMapping : ComplexTypeConfiguration<RoleType>
{
public RoleTypeMapping()
{
Property(r => r.Value)
.HasColumnName("RoleId"); // To make sure that in RoleType property of User EF entity maps to an int column [RoleId] in database (table [Users])
}
}
Using fluent-api, I want to create a foreign key association in [Users] table for [Users].[RoleId] referencing [Role].[Id]. Please can anyone provide me guidance to acheive this
I tired adding a property of type Role and creating a mapping through fluent-api, but EF creates another column Role_Id and makes it the foreign key. I want the existing [RoleId] column (complex type) to be the foreign key
It is not possible. If you want to have association with Role table you must abandon your enum-like approach and define Users entity like:
public class User
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public DateTime? DateOfBirth { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string EmailAddress { get; set; }
public Role Role { get; set; }
}
First of all relations are not enums and complex types cannot contain navigation properties (as well as foreign keys).

Using two keys in Entity Framework 4, One Identity and one Foreign?

Is it possible to map an Entity with one identity index that auto increments and a foreign key linking it to another table?
public class Item
{
public int ItemID { get; set; }
[StringLength(20)]
public string Barcode { get; set; }
[StringLength(50)]
public string Name { get; set; }
[StringLength(50)]
public string Description { get; set; }
public decimal Price { get; set; }
[ForeignKey("ItemCategory")]
public string CatID { get; set; }
public virtual ItemCategory ItemCategory { get; set; }
}
public class ItemCategory
{
// This should be the identity index
public int ItemCategoryID { get; set; }
// This should be the foreign key
public string CatID { get; set; }
public string Name { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
I saw this answer - should I configure my tables with modelbuilder?
Foreign key in Item must point to primary key in ItemCategory. FKs in EF behave in exactly same way as in databases. It means that FK must point to property with unique values in the principal entity. The problem is that EF doesn't support unique index / constraint so the only way to achieve uniqueness is primary key.
Because of that you cannot point your FK to CatID unless it is part of primary key but in such case you will have composite key containing both ItemCategoryID and CatID and your Item class will have to contain both of them to form correct FK.