说我们有:

public class Driver
{
    public int driverID { get; set; }
    public byte[] stamp { get; set; }
    public string name { get; set; }
    public string prename { get; set; }
}

简而言之,我正面临着这种情况。
 ...
 var myDriver = myCustomDBContext.Drivers.AsNoTracking()
                                         .Where(d => d.driverID == driverID)
                                         .SingleOrDefault();
 ...
 myDriver.name = "John";
 myDriver.prename = "Lennon";
 ...
 myCustomDBContext.Drivers.Attach(myDriver);
 myCustomDBContext.Entry(myDriver).State = EntityState.Modified;
 myCustomDBContext.SaveChanges();
 ...

结果是
 The column cannot be modified because it is an identity, rowversion or
     a system column. [Column name = stamp]

是否有任何方法可以强制对分离的实体进行更新,或者将此Rowversion列的变通办法不设置为“已修改”。

最佳答案

似乎您没有在模型中将stamp属性指定为行版本,而它只是一个二进制字段。您可以使用Fluent API进行指定:

modelBuilder.Entity<Driver>().Property(d => d.stamp)
    .IsRowVersion()
    .IsConcurrencyToken(false);

上面的代码适用于您不希望将stamp属性作为并发 token 的情况。 (默认情况下,rowversion是一个并发 token ,因此必须显式禁用它。)如果要将其作为并发 token ,则可以与Fluent API一起使用...
modelBuilder.Entity<Driver>().Property(d => d.stamp)
    .IsRowVersion();

...或带有数据注释:
[Timestamp]
public byte[] stamp { get; set; }

这将阻止EF为该属性编写UPDATE。

编辑

如果使用数据库优先策略,则[Timestamp]属性不起作用。此属性仅适用于Code-First开发。

当您使用Database-First时,连接字符串包含一个元数据部分,该部分引用了EDMX文件中定义的EDM:
connectionString="metadata=res://*/Model1.csdl
                          |res://*/Model1.ssdl
                          |res://*/Model1.msl;
                          ...
                          ..."

如果Entity Framework在连接字符串中找到此部分,则它不会在模型属性上使用数据注释,也不会处理Fluent API中的任何代码(根本不会调用OnModelCreating)。而是从嵌入式和编译的EDMX文件中加载映射定义。

这意味着,如果您想将stamp属性定义为并发 token ,则必须在EDMX文件中执行此操作。在XML中,它看起来像这样:

在SSDL部分中:

<Property Name="stamp" Type="timestamp" Nullable="false"
          StoreGeneratedPattern="Computed" />

在CSDL部分:

<Property Name="stamp" Type="Binary" Nullable="false" MaxLength="8"
          FixedLength="true"
          annotation:StoreGeneratedPattern="Computed"
          ConcurrencyMode="Fixed" />

您也可以在Visual Studio的模型设计器中对此进行定义:在设计器表面的实体中标记stamp属性,转到“属性”窗口,将“并发模式”设置为“固定”(还将“StoreGeneratedPattern”设置为“已计算”)。

您也可以从连接字符串中删除元数据部分。但这实际上意味着您从数据库优先转换为代码优先开发。然后,将尊重所有属性和Fluent API,但不再尊重EDMX中的任何定义。

关于c# - 如何处理EF 4.3.1设置修改Rowversion行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10353589/

10-12 17:08