[英]Guid string in primary key in Entity Framework Core
I have a problem regarding temporary values in primary keys in EF Core (2.1.4). 我对EF Core(2.1.4)中的主键中的临时值有问题。 The value is too long to fit in the database and validation using the DataAnnotations.Validator fails. 该值太长,无法放入数据库中,无法使用DataAnnotations.Validator进行验证。
If I disable the validator dbcontext.SaveChanges
works and handle the value in the correct way. 如果禁用验证器, dbcontext.SaveChanges
以正确的方式工作并处理该值。
I have an example table (SQL Server) with this definition: 我有一个具有此定义的示例表(SQL Server):
TestTable
Key1 numeric (18,0)
Key2 char (1) Default value: A
Key1
and Key2
are defined as primary key on the table. Key1
和Key2
被定义为表上的主键。 Key2
has a default value of A. Key2
的默认值为A。
This table is reverse engineered in EF Core to this POCO: 该表在EF Core中对此POCO进行了反向工程:
public partial class TestTable
{
[Column(TypeName = "numeric(18, 0)")]
public decimal Key1 { get; set; }
[StringLength(1)]
public string Key2 { get; set; }
}
Note that we are using data annotations on the POCO classes. 请注意,我们在POCO类上使用了数据注释。
The model generated looks like this: 生成的模型如下所示:
modelBuilder.Entity<TestTable>(entity =>
{
entity.HasKey(e => new { e.Key1, e.Key2 });
entity.Property(e => e.Key2)
.IsUnicode(false)
.HasDefaultValueSql("('A')");
});
I then add a new item to the dbcontext
. 然后,我向dbcontext
添加一个新项。
var testTbl = new TestTable { Key1 = 90};
db.TestTable.Add(testTbl);
db.Validate();
db.SaveChanges();
I don't specify Key2
as I want to use the default value from the database. 我没有指定Key2
因为我想使用数据库中的默认值。
Before I call Context.SaveChanges()
on the dbcontext I would like to validate the entities in the dbcontext. 在对dbcontext调用Context.SaveChanges()
之前,我想验证dbcontext中的实体。 This best way I have found for that until now is: 到目前为止,我发现的最佳方法是:
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.
}
}
}
My problem is that when I add the TestTable
object to the dbcontext, Key2
string property automatically get assigned a guid value. 我的问题是,当我将TestTable
对象添加到dbcontext时, Key2
字符串属性会自动获得一个guid值。 When Validate is called it fails because Key2
is not supposed to have a string value longer than 1 character. 调用Validate时失败,因为Key2
的字符串值不应超过1个字符。
If Key2
is not part of the primary key and I remove it from the HasKey method like this: 如果Key2
不是主键的一部分,我将其从HasKey方法中删除,如下所示:
entity.HasKey(e => new { e.Key1 });
Then Key2
don't get a guid value assigned and the validation works. 然后Key2
不会获得分配的guid值,并且验证有效。
Does someone know if there is a way to tell EF Core to not add a guid value to a string value that are part of a key and don't have a value specified? 有人知道是否有一种方法可以告诉EF Core不将guid值添加到键的一部分且没有指定值的字符串值中吗? Or is there a way to tell EF Core to obey the data annotation rules defined on the POCO object when assigning a temporary value? 还是有一种方法可以让EF Core在分配临时值时遵守POCO对象上定义的数据注释规则?
A composite primary key can only be defined by the fluent api. 复合主键只能由流利的api定义。
https://docs.microsoft.com/en-us/ef/core/modeling/keys https://docs.microsoft.com/en-us/ef/core/modeling/keys
Composite keys can only be configured using the Fluent API - conventions will never setup a composite key and you can not use Data Annotations to configure one. 只能使用Fluent API配置组合键-约定永远不会设置组合键,并且您不能使用数据注释来配置组合键。
However, you can even use data annotation. 但是,您甚至可以使用数据注释。
You can use the DatabaseGenerated
attribute. 您可以使用DatabaseGenerated
属性。
https://docs.microsoft.com/en-us/ef/core/modeling/generated-properties 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; }
}
If you want to use fluent api: 如果您想使用流利的api:
entity.Property(e => e.Key2)
.HasMaxLength(1)
.HasDefaultValueSql("('A')")
.ValueGeneratedOnAdd(); // add this
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.