How can I add a check constraint for JSON in Entity Framework?
As per the accepted answer, you'll need to add a migration. This is the EF Core syntax:
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.Sql("ALTER TABLE dbo.Data ADD CONSTRAINT CK_Data_JsonData_MustBeJson CHECK (IsJson(JsonData) = 1);"); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.Sql("ALTER TABLE dbo.Applications DROP CONSTRAINT CK_Data_JsonData_MustBeJson;"); }
I think that EF don't support any kind of CHECK constraints. The only thing that you can use is migration. See example in: Is it possible to add CHECK constraint with fluent API in EF7?
In EFCore 3+ this is now possible.
(Note: ISJSON is only available for SQL Server 2016+)
protected override void OnModelCreating(ModelBuilder modelBuilder){ base.OnModelCreating(modelBuilder); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var tableIdentifier = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table); foreach (var entityProperty in entityType.GetProperties()) { if (entityProperty.PropertyInfo != null && Attribute.IsDefined(entityProperty.PropertyInfo, typeof(JsonAttribute), inherit: true)) { var tableName = entityType.GetTableName(); var columnName = entityProperty.GetColumnName(tableIdentifier.Value); modelBuilder.Entity(clrType).HasCheckConstraint( name: $"CK_{tableName}_{columnName}_JSON", sql: $"ISNULL(ISJSON({columnName}), 1) = 1" ); } } } }
The JsonAttribute
is just a simple marker that I used for convenience:
[AttributeUsage(AttributeTargets.Property)]public class JsonAttribute : Attribute { }
Usage:
public class MyEntity{ public int Id { get; set; } [Json] public string JsonData { get; set; }}
Another possible alternative to using attributes would be using your own "convention" (e.g. property that is string and has a "Json" prefix/suffix)