How can I add a check constraint for JSON in Entity Framework? How can I add a check constraint for JSON in Entity Framework? json json

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)