实体框架5:使用DatabaseGeneratedOption.Computed选项

时间:2013-07-11 18:16:39

标签: ef-code-first entity-framework-5

我有一个使用[DatabaseGenerated(DatabaseGeneratedOption.Computed)]属性的EF5代码第一个项目。此选项会覆盖我的设置。

考虑这个SQL表:

CREATE TABLE Vehicle (
  VehicleId  int identity(1,1) not null,
  Name varchar(100) not null default ('Not Set')
)

我正在使用SQL默认构造来设置[Name]是未设置的情况。

在代码背后,我有一个类似于:

的类
public class Vehicle {
   ...

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string ShoulderYN { get; set; }
}

当我在代码中更新实体时,默认设置的值会覆盖我的新设置。

在代码中,我有(伪):

vehicle.Name = 'Update Name of Vehicle';
_dbContext.Update(vehicle);
_dbContext.SaveChanges();

预期结果是Vehicle.Name ='更新车辆名称'。

实际结果是Vehicle.Name ='Not Set'。

在EF5中是否有办法说“如果Vehicle.Name为空/空,请使用数据库中定义的值?否则,如果我在代码中设置值,我想使用此值。”

感谢。

史蒂夫

3 个答案:

答案 0 :(得分:15)

显然,没有。这不是那么聪明:)

正如您可能已经读过的那样,Computed选项只是告诉EF不要更新您的列,因为您将自己计算DB端的值。然后EF将从您的数据库中返回新计算的值(在您的情况下为“未设置”)。

您的基本三个选项是 - 根据EF源代码文档:

  • 无 - 数据库不生成值。
  • Identity - 数据库在插入行时生成值。
  • 已计算 - 数据库在插入或更新行时生成值。

https://github.com/aspnet/EntityFramework6/blob/527ae18fe23f7649712e9461de0c90ed67c3dca9/src/EntityFramework/DataAnnotations/Schema/DatabaseGeneratedOption.cs

由于您希望完成更多的自定义逻辑,我担心您必须自己完成。我建议你不要再依赖数据库默认约束,而是先用代码做一切。这样你就会得到类似的代码:

public class Vehicle
{
  public Vehicle()
  {
    this.Name = "Not set";
  }

  // Without 'Generated' attribute
  public string Name { get; set; }
}

这样,当您创建实体时,它会自动以预期的默认值启动。稍后可以通过简单地修改Name属性来进行更改。

希望它有所帮助!

答案 1 :(得分:0)

我检查了几个小时以获得好的答案,但没有: EF无法通过自动生成的ID更新模型。

您有3个选项:

  1. 将另一个VehicleId添加到Vehicle model。
  2. 将自动生成的ID更改为由您手动生成。
  3. 将唯一标识符设置为其他内容,然后将您生成的ID设置为 模型。 在您的车辆类中,它可以是名称属性。
  4. 我建议你选择3: 将unique-id设置为Vehicle.Name(您可以添加更多属性)。 然后:如果不存在唯一ID的车辆,则将新车辆添加到db-context:

    //if there is no such a Vehicle in system, add it:
    if (vehicle.Name !=null && vehicle.Name != String.Empty && _dbContext.Where(v => v.Name == vehicle.Name).FirstOrDefault() == null)
        _dbContext.Add(vehicle);
    
    _dbContext.SaveChanges();
    

答案 2 :(得分:0)

实际上有一个简单的解决方案:

  • 您需要在表创建脚本中保留默认约束值,就像现在一样:

    CREATE TABLE Vehicle (
      VehicleId  int identity(1,1) not null,
      Name varchar(100) not null default ('Not Set')
    )
    
  • 只需从类定义中的属性中删除DatabaseGenerated属性:

    public class Vehicle {
       ...
    
       [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
       public string ShoulderYN { get; set; }
    }
    

就是这样:现在只有在代码中没有指定某个值时,数据库才会使用默认值。希望这会有所帮助。