Entity Framework DbContext Validation API

先建一張資料表,並加上幾個Attribute當例子

namespace ConsoleApplication1.Models
{
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Table(“Table1”)]
public class Table1
{
[Key]
public int Table1Id { get; set; }

[Required]
[StringLength(10, MinimumLength = 2)]
public string C1 { get; set; }

[Range(10, 20)]
public int C2 { get; set; }

public DateTime D1 { get; set; }

public DateTime D2 { get; set; }
}
}

針對屬性驗證
namespace ConsoleApplication1
{
using ConsoleApplication1.Models;
using System;
using System.Data.Entity;

class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<DemoContext>());
using (DemoContext db = new DemoContext())
{
db.Database.Initialize(false);

Table1 table1 = new Table1
{
C1 = “a”,
C2 = 1,
D1 = DateTime.Now,
D2 = DateTime.Now.AddDays(-1)
};

foreach (var item in db.Entry(table1).Property(x => x.C1).GetValidationErrors())
{
Console.WriteLine(item.ErrorMessage);
}

foreach (var item in db.Entry(table1).Property(x => x.C2).GetValidationErrors())
{
Console.WriteLine(item.ErrorMessage);
}
}
}
}
}

針對實體驗證
namespace ConsoleApplication1
{
using ConsoleApplication1.Models;
using System;
using System.Data.Entity;

class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<DemoContext>());
using (DemoContext db = new DemoContext())
{
db.Database.Initialize(false);

Table1 table1 = new Table1
{
C1 = “a”,
C2 = 1,
D1 = DateTime.Now,
D2 = DateTime.Now.AddDays(-1)
};

foreach (var item in db.Entry(table1).GetValidationResult().ValidationErrors)
{
Console.WriteLine(item.ErrorMessage);
}
}
}
}
}

針對DbContext驗證
namespace ConsoleApplication1
{
using ConsoleApplication1.Models;
using System;
using System.Data.Entity;

class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<DemoContext>());
using (DemoContext db = new DemoContext())
{
db.Database.Initialize(false);

Table1 table1 = new Table1
{
C1 = “a”,
C2 = 1,
D1 = DateTime.Now,
D2 = DateTime.Now.AddDays(-1)
};

db.Table1.Add(table1);
foreach (var result in db.GetValidationErrors())
{
foreach (var item in result.ValidationErrors)
{
Console.WriteLine(item.ErrorMessage);
}
}
}
}
}
}

輸出的畫面如下

自定義驗證屬性規則,加入一個靜態類別,用來放自定義的驗證規則
namespace ConsoleApplication1.Models
{
using System.ComponentModel.DataAnnotations;

public static class MyCustomRule
{
public static ValidationResult MyStringRule(string value)
{
if (value == “a”)
{
return new ValidationResult(“字串不可為a”);
}
else
{
return ValidationResult.Success;
}
}

public static ValidationResult MyIntRule(int value)
{
if (value == 1)
{
return new ValidationResult(“數字不可為1”);
}
else
{
return ValidationResult.Success;
}
}
}
}

在屬性上加入自定義的驗證規則
namespace ConsoleApplication1.Models
{
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Table(“Table1”)]
public class Table1
{
[Key]
public int Table1Id { get; set; }

[Required]
[StringLength(10, MinimumLength = 2)]
[CustomValidation(typeof(MyCustomRule), “MyStringRule”)]
public string C1 { get; set; }

[Range(10, 20)]
[CustomValidation(typeof(MyCustomRule), “MyIntRule”)]
public int C2 { get; set; }

public DateTime D1 { get; set; }

public DateTime D2 { get; set; }
}
}

驗證資料的時後,就會包含自定義的規則

自定義驗證實體規則,在實體上實作IValidatableObject介面
namespace ConsoleApplication1.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

[Table(“Table1”)]
public class Table1 : IValidatableObject
{
[Key]
public int Table1Id { get; set; }

[Required]
// [StringLength(10, MinimumLength = 2)]
public string C1 { get; set; }

// [Range(10, 20)]
public int C2 { get; set; }

public DateTime D1 { get; set; }

public DateTime D2 { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (this.C1 == “a”)
{
yield return new ValidationResult(“字串不可為a”);
}

if (this.C2 == 1)
{
yield return new ValidationResult(“數字不可為1”);
}

if (this.D1 >= this.D2)
{
yield return new ValidationResult(“d1不能大於d2”);
}
}
}
}

自定義驗證DbContext規則,覆寫ValidateEntity函式
namespace ConsoleApplication1.Models
{
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;

public class DemoContext : DbContext
{
public DbSet<Table1> Table1 { get; set; }
public DbSet<Table2> Table2 { get; set; }

protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
var result = base.ValidateEntity(entityEntry, items);
var table1 = entityEntry.Entity as Table1;
if (table1 != null)
{
if (table1.C1 == “a”)
{
result.ValidationErrors.Add(new DbValidationError(“C1”, “字串不可為a”));
}

if (table1.C2 == 1)
{
result.ValidationErrors.Add(new DbValidationError(“C2”, “數字不可為1”));
}

if (table1.D1 >= table1.D2)
{
result.ValidationErrors.Add(new DbValidationError(“D1”, “d1不能大於d2”));
}
}

return result;
}
}
}
輸出的結果如下