Entity framework 和 SQL CE 不允许零值?
Entity framework with SQL CE don't allow zero values?
我有以下非常简单的代码:
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 都是新手,但这看起来像个错误,不是吗?
我在桌面 Windows 8.1.
上使用 EF(6.x) 和 SQL CE(4.x) 的最新可用 Nuget 包
更新:
创建 table 脚本:
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
如果您将一个字段命名为 "Id" 或(以您的实体为例)"TesteeId",并且您没有使用数据属性或流畅的 [=34] 将另一个字段指定为主键=],则 Entity Framework 假定该字段是主键。
如果是int或long,那么它会假定你想让数据库生成key,它会在table.
中放一个IDENTITY字段
然后发生的是,当您添加实体并调用 SaveChanges()
时,Entity Framework 插入数据,检索数据库生成的键并更新实体。您添加的第一个 ID 为 1,下一个为 2,依此类推。
如果不想让key由数据库生成,那么可以添加一个data属性:
[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);
}
注意:如果在 table 生成后以这种方式更改 Id 字段,则 EF 不会从该字段中删除 IDENTITY。这是一个非常重要的操作,因为可能必须为现有数据重新生成外键。您必须强制删除并重新创建 table,或者自己修复它。
参考:
我有以下非常简单的代码:
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 都是新手,但这看起来像个错误,不是吗?
我在桌面 Windows 8.1.
上使用 EF(6.x) 和 SQL CE(4.x) 的最新可用 Nuget 包更新: 创建 table 脚本:
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
如果您将一个字段命名为 "Id" 或(以您的实体为例)"TesteeId",并且您没有使用数据属性或流畅的 [=34] 将另一个字段指定为主键=],则 Entity Framework 假定该字段是主键。
如果是int或long,那么它会假定你想让数据库生成key,它会在table.
中放一个IDENTITY字段然后发生的是,当您添加实体并调用 SaveChanges()
时,Entity Framework 插入数据,检索数据库生成的键并更新实体。您添加的第一个 ID 为 1,下一个为 2,依此类推。
如果不想让key由数据库生成,那么可以添加一个data属性:
[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);
}
注意:如果在 table 生成后以这种方式更改 Id 字段,则 EF 不会从该字段中删除 IDENTITY。这是一个非常重要的操作,因为可能必须为现有数据重新生成外键。您必须强制删除并重新创建 table,或者自己修复它。
参考: