13

我有一个使用该[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 = 'Update Name of Vehicle'
实际结果是Vehicle.Name = 'Not Set'

EF5 中有没有办法说:
如果 Vehicle.Name 为空/空,则使用数据库中定义的值?否则,如果我在代码中设置值,我想使用这个值。

4

3 回答 3

15

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

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

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

  • 无 - 数据库不生成值。
  • 身份 - 数据库在插入一行时生成一个值。
  • Computed - 数据库在插入或更新行时生成一个值。

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 属性来更改。

希望能帮助到你!

于 2013-12-27T12:38:45.930 回答
0

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

您有 3 个选项:

  1. 将另一个 VehicleId 添加到 Vehicle 模型。
  2. 将自动生成的 ID 更改为由您手动生成。
  3. 将唯一标识符设置为其他内容,然后是模型中的生成 ID。在您的车辆类中,它可以是名称属性。

我建议您选择 3:将唯一 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();
于 2015-08-27T16:26:13.323 回答
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; }
    }
    

就是这样:现在数据库将仅在您未在代码中指定某些值时使用默认值。希望这可以帮助。

于 2015-11-02T11:47:20.517 回答