![](/img/trans.png)
[英]Autogenerate GUID column that is not a primary key in Entity Framework
[英]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
Key1
和Key2
被定义为表上的主键。 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.