Am Trying to create Two Tables like bellow got some EF error.
public class Student : ModelsBase
{
public string AdharNumber { get; set; }
public byte Religion { get; set; }
public int CategoryID { get; set; }
public string Cast { get; set; }
public string SubCast { get; set; }
public string Photo { get; set; }
public DateTime DateOfJoining { get; set; } = DateTime.Now;
[Required]
public ICollection<Address> TemporaryAddress { get; set; }
[Required]
public ICollection<Address> PermanentAddress { get; set; }
}
public class Address : ModelsBase
{
public string DoorNo { get; set; }
public string StreetLocality { get; set; }
public string Landmark { get; set; }
public string City { get; set; }
public int Taluk { get; set; }
public int District { get; set; }
public int State { get; set; }
public string Pincode { get; set; }
public bool IsPermanent { get; set; } = true;
public bool IsDefault { get; set; } = true;
[ForeignKey("Student")]
public Guid StudentId { get; set; }
}
Getting the bellow error while trying to Run the "Add-Migration command"
Both relationships between 'Address' and 'Student.PermanentAddress' and between 'Address' and 'Student.TemporaryAddress' could use {'StudentId'} as the foreign key. To resolve this, configure the foreign key properties explicitly in 'OnModelCreating' on at least one of the relationships
Please help. Thanks!
CodePudding user response:
Your issue is that from the Address side of things you have a Many-to-1 with a single Student, but from the Student side of things you want 2x 1-to-Many relationships.
Since The relationship is really just a 1-to-Many from the student that you want to discriminate between temporary and permanent addresses:
public class Student : ModelsBase
{
public string AdharNumber { get; set; }
public byte Religion { get; set; }
public int CategoryID { get; set; }
public string Cast { get; set; }
public string SubCast { get; set; }
public string Photo { get; set; }
public DateTime DateOfJoining { get; set; } = DateTime.Now;
[Required]
public ICollection<Address> Addresses { get; set; } = new List<Address>();
[NotMapped]
public ICollection<Address> TemporaryAddresses => Addresses.Where(x => !x.IsPermanent).ToList();
[NotMapped]
public ICollection<Address> PermanentAddresses => Addresses.Where(x => x.IsPermanent).ToList();
}
With 1-to-many collections I recommend initializing them to an empty list to avoid null reference exceptions especially if lazy loading is disabled.
The caveat here is that from EF's perspective, Student only has the Addresses collection, do not attempt to use either TemporaryAddresses or PermanentAddresses in a query expression as these are unmapped accessors. If you want to filter based on a permanent address you will have to do it through Addresses and include the condition on IsPermanent in the query.
For example:
// Not valid...
var studentsInDetroit = context.Students.Where(x => x.PermanentAddresses.Any(a => a.City == "Detroit")).ToList();
// Valid...
var studentsInDetroit = context.Students.Where(x => x.Addresses.Any(a => a.IsPermanent && a.City == "Detroit")).ToList();
Normally I don't recommend using unmapped accessors in entities because of this. It is generally better to leave entities representing pure domain/data state and project that down to view models which can be more concerned about splitting the data into a more palatable form for consumption.