2015-04-30 40 views
0

我有以下非常简单的代码:使用SQL CE的实体框架不允许使用零值?

using System; 
using System.Data.Entity; 

namespace TestCSharp 
{ 
    public class Testee 
    { 
     public long Id { get; set; } 
     public string Name { get; set; } 
     public Testee() 
     { 
     } 

     public Testee(long id, string name) 
     { 
      Id = id; 
      Name = name; 
     } 
    } 

    public class DatabaseContext : DbContext 
    { 
     public DatabaseContext() 
      : base("name=MyContext") 
     { 
     } 

     public DbSet<Testee> Testees { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var dbContext = new DatabaseContext(); 
      var testData = new Testee(0, "name"); 
      dbContext.Testees.Add(testData); 
      dbContext.SaveChanges(); 
      Console.WriteLine("Id: {0}", testData.Id); 
     } 
    } 
} 

而且我认为它应该打印0但实际上它打印1。如果我使用除0以外的任何其他值,那么我会得到该值。当我问它时,它增加了一行1而不是0。零值有什么问题?我对EF和SQL CE都是新手,但看起来像一个bug,不是?

我在桌面Windows 8.1上使用EF(6.x)和SQL CE(4.x)的最新Nuget包。

UPD: 创建表脚本:

CREATE TABLE [Testees] (
    [Id] bigint IDENTITY (1,1) NOT NULL 
, [Name] nvarchar(4000) NULL 
); 
GO 
ALTER TABLE [Testees] ADD CONSTRAINT [PK_dbo.Testees] PRIMARY KEY ([Id]); 
GO 
+0

你能脚本的CREATE TABLE脚本测试对象的表。 – ErikEJ

+0

@ErikEJ,更新(似乎与您的工具,我做了一代 - 感谢该工具!)。看起来问题是'IDENTITY(1,1)',对吧?我不应该明确要求EF添加这个IDENTITY而不是它自己做这件事吗? – ixSci

回答

1

如果命名字段,“ID”或(使用实体为例)“TesteeId”你没有指定其他字段作为主键使用数据属性或流利的API,那么实体框架假定该字段是主键。

如果它是一个int或一个long,那么它会假定您希望数据库生成密钥,并且它会在表中放置一个IDENTITY字段。

然后会发生的事情是,当您添加实体并呼叫SaveChanges()时,实体框架会插入数据,检索由数据库生成的密钥并更新实体。您添加的第一个具有标识1,下一个会是2等

如果你不想被数据库中生成的密钥做,那么你可以添加一个数据属性:

[DatabaseGenerated(DatabaseGeneratedOption.None)] 
public long Id { get; set; } 

,或者使用流畅API:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Testee>() 
     .Property(e => e.Id) 
     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 
} 

注意:如果更改已生成的表后,这样的标识字段,然后EF不会删除从外地身份。这是一个不平凡的操作,因为外键可能需要重新生成现有的数据。您必须强制删除并重新创建表格,或者自行修复它。

参考:

https://stackoverflow.com/a/18917348/150342

+0

为什么只有'0'才会发生?例如,如果我将'Id'设置为'2',那么'SaveChanges'完成不是'3'后,我的'testData'对象将'Id'设置为'2'。 – ixSci

+0

EF不会将值发送到数据库,数据库会生成该值。 IDENTITY字段自动递增http://www.w3schools.com/sql/sql_autoincrement.asp。当您将Id设置为2并且testData返回2时,这是因为最后插入的值为1.巧合。 – Colin