I'm basically trying to enforce this in Entity Framework: Require Only One Of Multiple Columns Be Not Null
My database has several 1:m relationships where the child entity belongs to one of several parent entities. For example, let's say I have tables for Teachers
, Students
, and Guardians
. Each of those can have many PhoneNumbers
and EmailAddresses
. I am using EF Code First, and my models look something like:
public class Teacher {
public int Id { get; set; }
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
}
public class Student {
public int Id { get; set; }
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
}
public class Guardian {
public int Id { get; set; }
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
}
public class PhoneNumber {
public int Id { get; set; }
public string Number { get; set; }
}
public class EmailAddress {
public int Id { get; set; }
public string Email { get; set; }
}
When I run the migration, this creates the database with the tables/columns I would expect. The PhoneNumbers
and EmailAddresses
tables each have columns Teacher_Id
, Student_Id
, and Guardian_Id
, which are foreign keys to their respective parent entity. However, there are no constraints on how many parent entities can be set on the child. For example, I can create a PhoneNumber
that has all three parent IDs set to null, or I can set both a Teacher_Id
and a Guardian_Id
.
I tried adding a required attribute to the parents like so:
public class Teacher { // Also Student/Guardian
public int Id { get; set; }
public string Name { get; set; }
[Required]
public List<PhoneNumber> PhoneNumbers { get; set; }
[Required]
public List<EmailAddress> EmailAddresses { get; set; }
}
That does not seem to have any effect.
I think there is no way to do this on entities. Instead, create a migration and try to alter the table in migration class like this:
public partial class YourMigrationName: Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("ALTER TABLE [dbo].[PhoneNumber]
WITH CHECK ADD CONSTRAINT [CK_PhoneNumer_Teacher_Student_Guardian] CHECK (Teacher_Id
is not null or Student_Id is not null or Guardian_Id is not null)
GO
ALTER TABLE [dbo].[EmailAddress] WITH CHECK ADD CONSTRAINT
[CK_EmailAddress_Teacher_Student_Guardian] CHECK (Teacher_Id is not null or
Student_Id is not null or Guardian_Id is not null)
");
}
}
Try this:
public class PhoneNumber
{
public int Id { get; set; }
public string Number { get; set; }
//Added this code:
[Required]
public Teacher Teacher { get; set;}
}
public class EmailAddress {
public int Id { get; set; }
public string Email { get; set; }
//Added this code:
[Required]
public Teacher Teacher { get; set;}
}
That would make sure you cannot create PhoneNumber without Teacher. You can also do this:
public class PhoneNumber
{
public int Id { get; set; }
public string Number { get; set; }
public int TeacherId
public Teacher Teacher { get; set;}
}
That would also detect that you want to add constraint on your PhoneNumber. Both ways work fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.