簡體   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