繁体   English   中英

Entity Framework Core主键中的引导字符串

[英]Guid string in primary key in Entity Framework Core

我对EF Core(2.1.4)中的主键中的临时值有问题。 该值太长,无法放入数据库中,无法使用DataAnnotations.Validator进行验证。
如果禁用验证器, dbcontext.SaveChanges以正确的方式工作并处理该值。

我有一个具有此定义的示例表(SQL Server):

TestTable
Key1 numeric (18,0)
Key2 char (1) Default value: A

Key1Key2被定义为表上的主键。 Key2的默认值为A。

该表在EF Core中对此POCO进行了反向工程:

public partial class TestTable
{
    [Column(TypeName = "numeric(18, 0)")]
    public decimal Key1 { get; set; }
    [StringLength(1)]
    public string Key2 { get; set; }
}

请注意,我们在POCO类上使用了数据注释。

生成的模型如下所示:

modelBuilder.Entity<TestTable>(entity =>
{
    entity.HasKey(e => new { e.Key1, e.Key2 });
    entity.Property(e => e.Key2)
        .IsUnicode(false)
        .HasDefaultValueSql("('A')");
});

然后,我向dbcontext添加一个新项。

var testTbl = new TestTable { Key1 = 90};
db.TestTable.Add(testTbl);
db.Validate();
db.SaveChanges();

我没有指定Key2因为我想使用数据库中的默认值。

在对dbcontext调用Context.SaveChanges()之前,我想验证dbcontext中的实体。 到目前为止,我发现的最佳方法是:

Public void Validate()
{
    var entities = ChangeTracker.Entries()
    .Where(e => e.State == EntityState.Added || 
    e.State == EntityState.Modified)
    .Select(e => e.Entity)
    .ToList();

    foreach (var entity in entities)
    {
        var vContxt = new ValidationContext(entity);
        List<ValidationResult> validaRes = new List<ValidationResult>();

        if (!Validator.TryValidateObject(entity, validationContext, 
            validationResults, true))
        {
            //Handle validation errors.
        }
    }
}

我的问题是,当我将TestTable对象添加到dbcontext时, Key2字符串属性会自动获得一个guid值。 调用Validate时失败,因为Key2的字符串值不应超过1个字符。

如果Key2不是主键的一部分,我将其从HasKey方法中删除,如下所示:

entity.HasKey(e => new { e.Key1 });

然后Key2不会获得分配的guid值,并且验证有效。

有人知道是否有一种方法可以告诉EF Core不将guid值添加到键的一部分且没有指定值的字符串值中吗? 还是有一种方法可以让EF Core在分配临时值时遵守POCO对象上定义的数据注释规则?

复合主键只能由流利的api定义。
https://docs.microsoft.com/en-us/ef/core/modeling/keys

只能使用Fluent API配置组合键-约定永远不会设置组合键,并且您不能使用数据注释来配置组合键。

但是,您甚至可以使用数据注释。
您可以使用DatabaseGenerated属性。
https://docs.microsoft.com/en-us/ef/core/modeling/generated-properties

public partial class TwoKeysTable
{
    public decimal Key1 { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public string Key2 { get; set; }

    public string Test { get; set; }
}

如果您想使用流利的api:

entity.Property(e => e.Key2)
         .HasMaxLength(1)
         .HasDefaultValueSql("('A')")
         .ValueGeneratedOnAdd(); // add this 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM