问题
I'm using EF Core.
My Customer
entity has properties Address1
, Address2
, and AddressFull
.
Depending on which system sends me the data, I may receive Address1
and Address2
, or I may receive AddressFull
.
So I need:
- EITHER
Address1
andAddress2
required, andAddressFull
not-required - OR
Address1
andAddress2
not-required, andAddressFull
required
So I have:
entityTypeBuilder.Property(p => p.Address1).IsRequired(false);
entityTypeBuilder.Property(p => p.Address2).IsRequired(false);
entityTypeBuilder.Property(p => p.AddressFull).IsRequired(false);
But this config does not properly map to my domain, and I want to enforce the logic. Is that possible in EF Core?
回答1:
In general, there are two ways to implement this type of complex domain logic. You can do it in the database using CHECK
constraints or triggers, or you can do it in your domain objects and check them during SaveChanges
. Here is an example of the latter.
class MyEntity : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (string.IsNullOrEmpty(Address1)
&& string.IsNullOrEmpty(Address2)
&& string.IsNullOrEmpty(AddressFull))
{
yield return new ValidationResult("An address is required.");
}
}
}
class MyContext : DbContext
{
public override int SaveChanges()
{
var entities = from e in ChangeTracker.Entries()
where e.State == EntityState.Added
|| e.State == EntityState.Modified
select e.Entity;
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(
entity,
validationContext,
validateAllProperties: true);
}
return base.SaveChanges();
}
}
回答2:
You need to allow for your DbContext different mapping according to your scenario, you can check this answer to enable in your DbContext change the mapping:
Dynamically changing schema in Entity Framework Core
来源:https://stackoverflow.com/questions/41097493/how-do-i-enforce-an-either-or-relationship-between-model-properties-using-ef-co