EntityFramework DatabaseGeneratedOption.Identity接受并保存数据,而不是生成新数据

时间:2017-05-23 00:29:33

标签: entity-framework entity-framework-core

假设这个测试模型:

public class TestEntity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }
}

当我生成新的实例时,Id00000000-0000-0000-0000-000000000000

将此类实例保存在数据库中作为新行会导致生成Guid(与空行不同)。

但是,如果我在TestEntity.Id中提供有效的Guid,则会使用提供的Guid而不是新计算的Guid创建新行。

我希望此行为仅在编辑行时存在,而不是在创建行时存在。这是为了确保数据库层免受攻击,用户通常无法选择输入哪些数据。

当然,这种保护存在于其他层中,但我也想在数据库中使用它。这可能吗?如何在创建新行时告诉EF忽略模型数据?

DatabaseGeneratedOption.Computed说明

  

数据库在插入或更新行时生成值

如此清楚,这不是一种选择。我不想在更新行时更改Id。我只想确定没有人可以创建一行并选择Id。

1 个答案:

答案 0 :(得分:1)

我试着保持简单。让您的set方法受到保护,然后您有两种方法来生成Ids,您可以在构造函数中自己生成它:

public class TestEntity
{
    // no need to decorate with `DatabasGenerated`, since it won't be generated by database...
    [Key]
    public Guid Id { get; protected set; }
    public string Name { get; set; }

    public TestEntity()
    {
        this.Id = Guid.NewGuid();
    }
}

...或者你可以让数据库为你生成它。至少对于SQL Server,它也可以生成intGuid

public class TestEntity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public Guid Id { get; protected set; }
    public string Name { get; set; }

    // no need to generate a Guid by yourself....

}

这样可以避免人们在课堂外设置Id值(因此没有人可以为新行选择Guid,或者从现有行中修改)。 当然,您的团队可以使用反射来绕过类定义,但如果是这样的话,您需要与您的团队进行交流。

如果您仍然想确保他们不会作弊,那么在保存对数据库的更改之前您必须先进行检查,这可能会覆盖您的SaveChanges() DbContext

  

作为旁注,对于intGuid,实体框架不会生成值。使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]修饰属性将告诉Entity Framework生成一个具有来自自己的数据库提供程序的默认值的列。