When it comes to a single object's foreign key, we would have a property:
SingleMap.cs
[ForeignKey("ApplicationUser")]
public int ApplicationUserID { get; set; }
public ApplicationUser ApplicationUser { get; set; }
How do we map the foreignkey when we have a list of ApplicationUsers?
ManyMap.cs
public ICollection<ApplicationUser> ApplicationUserList { get; set; }
it is usually used this way:
public class ManyMap
{
public int ID {get; set;}
.....
[InverseProperty(nameof(ApplicatonUser.ManyMap))]
public ICollection<ApplicationUser> ApplicationUsers{ get; set; }
}
public class ApplicationUser
{
......
public int ManyMapID { get; set; }
[ForeignKey(nameof(ManyMapID))]
[InverseProperty("ApplicationUsers")]
public ManyMap ManyMap { get; set; }
}
Related
Here are Entities:
public class Entity
{
public int Id { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
}
public class EntityBase : Entity
{
[ForeignKey("CreatedBy")]
public int CreatedById { get; set; }
public User CreatedBy { get; set; }
[ForeignKey("ModifiedBy")]
public int? ModifiedById { get; set; }
public User ModifiedBy { get; set; }
}
public class ProjectRequest : EntityBase
{
public string RequestTitle { get; set; }
public string RequestType { get; set; }
...
public virtual ICollection<Material> Materials { get; set; }
public virtual ICollection<Translation> Translations { get; set; }
}
public class Material : EntityBase
{
[ForeignKey("ProjectRequest")]
public int ProjectRequestId { get; set; }
public virtual ProjectRequest ProjectRequest { get; set; }
...
public virtual ICollection<Translation> Translations { get; set; }
}
public class Translation:EntityBase
{
[ForeignKey("ProjectRequest")]
public int ProjectRequestId { get; set; }
public virtual ProjectRequest ProjectRequest { get; set; }
[ForeignKey("Material")]
public int MaterialId { get; set; }
public virtual Material Material { get; set; }
public string ProductMasterText { get; set; }
[MaxLength(40)]
public string ShortDescription { get; set; }
public string MasterDescriptionLine1 { get; set; }
public string MasterDescriptionLine2 { get; set; }
public string MasterDescriptionLine3 { get; set; }
public string LanguageCode { get; set; }
}
No modifications has been done to these entities using fluent API.
Now, whenever I try to insert object of type ProjectRequest with Materials and Translations nested in it, in Translation objects ProjectRequestId is set to 0.
Following is sample Change Tracker snapshot:
Can anyone help me on this? Why ProjectRequestId is 0 but MaterialId properly assigned in Transaltion objects?
I use EF's code first approach. I have the following three classes:
public class Inquiry
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public virtual ApplicationUser CreatedBy { get; set; }
public virtual Contractor Contractor { get; set; }
public IList<ApplicationUser> InquiryUsers { get; set; }
public IList<InquiryComment> Comments { get; set; }
public IList<HydroTechEmail> Emails { get; set; }
public InquiryState State { get; set; }
public List<string> Attachments { get; set; }
public DateTime? TimeOfCreation { get; set; }
public DateTime? TimeOfModification { get; set; }
}
public class HydroTechEmail
{
public Guid Id { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
public string FromDisplayName { get; set; }
public string FromAddress { get; set; }
public List<string> ToDisplayName { get; set; }
public List<string> ToAddress { get; set; }
public HydroTechEmailState State { get; set; }
public DateTime? ReceivedTime { get; set; }
public virtual List<HydroTechEmailAttachment> Attachments { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
public class ApplicationUser
{
public Guid Id {get;set;}
public string Firstname {get;set;}
public string Lastname {get;set;}
}
I thought EF will generate some intermediate classes for relation Inquiry -> Many Emails and Inquiry -> Many Application Users. Instead it created a foreign keys in ApplicationUser and HydroTechEmail classes to Inquiry class. How should I create this one to many relations?
The strange is that for Comments it created an intermediate table named InquiryComments.
Entity Framework will only generate intermediate tables for many-to-many relationships.
For one-to-many relationships, no intermediate tables will be created because it is not necessary.
I have created an application in entityframework using code first method.
In application , there are two entities which have many to many relationship between them.
public class Course
{
[Key]
public int CourseId { get; set; }
public string Name { get; set; }
public ICollection<Student> Student{ get; set; }
}
public class Student
{
[Key]
public int StudentId { get; set; }
public string Name { get; set; }
public ICollection<Course> Course{ get; set; }
}
when I execute the project, it creates student table,Course table,StudentCourse table.
Now now the problem is,in StudentCourse table there are only two keys, StudentID and CourseId
I want to add additional column in that table how to do that ?
Declare a class defining that table:
public class Course
{
[Key]
public int CourseId { get; set; }
public string Name { get; set; }
public ICollection<Student> Student{ get; set; }
}
public class Student
{
[Key]
public int StudentId { get; set; }
public string Name { get; set; }
public ICollection<Course> Course{ get; set; }
}
public class StudentCourse
{
public int StudentId { get; set; }
public int CourseId { get; set; }
//More columns here
}
I am new to EF code first and am trying to force an ICollection navigation property to use a specific relationship table I've manually created for mapping the entities.
The reason I am forced to do it is that I have a TenantId column on all my tables. Is this somehow possible?
[Table("Tenants")]
public class Tenant
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
// This should use ContactAddressesForTenants table
public virtual ICollection<Address> ContactAddresses {get; set;}
}
[Table("BusinessProfiles")]
public class BusinessProfile
{
[Key, ForeignKey("Tenant")]
public int TenantId { get; set; }
public virtual Tenant Tenant { get; set; }
// This should use the AddressesForBusinessProfiles table
public virtual ICollection<Address> ProfileAddresses { get; set; }
}
[Table("Addresses")]
public class Address
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("Tenant")]
public int TenantId { get; set; }
}
[Table("ContactAddressesForTenants")]
public class ContactAddressForTenant
{
[ForeignKey("Tenant")]
public int TenantId { get; set; }
[ForeignKey("Address")]
public int AddressId { get; set; }
public virtual Tenant Tenant { get; set; }
public virtual Address Address {get; set;}
}
[Table("AddressesForBusinessProfiles")]
public class AddressForBusinessProfile
{
[ForeignKey("BusinessProfile")]
public int TenantId { get; set; }
[ForeignKey("Address")]
public int AddressId { get; set; }
public virtual BusinessProfile BusinessProfile { get; set; }
public virtual Address Address { get; set; }
}
If I am understanding you correctly.
You can try changing this in your model.
Where it is:
// This should use ContactAddressesForTenants table
public virtual ICollection<Address> ContactAddresses {get; set;}
// This should use the AddressesForBusinessProfiles table
public virtual ICollection<Address> ProfileAddresses { get; set; }
Change to:
public virtual ICollection<ContactAddressForTenant> ContactAddresses {get; set;}
public virtual ICollection<AddressForBusinessProfile> ProfileAddresses { get; set; }
In have two classes;
public class Item
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual BinCard BinCard { get; set; }
}
and
public class BinCard
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int ItemId { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
public double Qty { get; set; }
public ObservableCollection<Item> Item { get; set; }
}
The BinCard.Id is the PK and auto increments.
I want the relationship between two tables using Item.Id and BinCard.ItemId using*FluentAPI*.
Please help me to create this relationship correctly.
EF does not support non-PK principal Ids because it doesn't support unique keys other than PKs yet. To make this work you will have to create relationship based on BinCard.Id and BinCardId to Item entity - btw. it looks like the correct way to build relationship in your model. Your current model looks really strange.
Thanks for all replies. This is the solution for my question.
public class BinCard
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int ItemId { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
public double Qty { get; set; }
public virtual Drug Drug { get; set; }
}
public class Item
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public ObservableCollection<BinCard> BinCard { get; set; }
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Drug>()
.HasRequired(s => s.Stock)
.WithRequiredPrincipal(s => s.Drug);
}