问题描述
|
是否可以使用CodeFirst设计为新的Entity Framework 4.1中的对象实现Guid COMB身份策略?我以为将“ 0”设置为有效,但仍然可以使用普通的GUID。
解决方法
我猜您正在使用SQL Server作为数据库。这是不同MS工具之间不一致的一个很好的例子。 SQL Server团队不建议将ѭ1用作
UNIQUEIDENTIFIER
列的默认值,如果您在数据库中将Guid
属性指定为自动生成,则ADO.NET团队会使用它。他们应该改用newsequentialid()
!
如果要由数据库生成顺序的Guid,则必须修改生成的表,这确实很复杂,因为必须找到自动生成的默认约束,然后删除它并创建新约束。所有这些都可以在自定义数据库初始化程序中完成。这里有我的示例代码:
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new CustomInitializer());
using (var context = new Context())
{
context.TestEntities.Add(new TestEntity() { Name = \"A\" });
context.TestEntities.Add(new TestEntity() { Name = \"B\" });
context.SaveChanges();
}
}
}
public class CustomInitializer : DropCreateDatabaseAlways<Context>
{
protected override void Seed(Context context)
{
base.Seed(context);
context.Database.ExecuteSqlCommand(@\"
DECLARE @Name VARCHAR(100)
SELECT @Name = O.Name FROM sys.objects AS O
INNER JOIN sys.tables AS T ON O.parent_object_id = T.object_id
WHERE O.type_desc LIKE \'DEFAULT_CONSTRAINT\'
AND O.Name LIKE \'DF__TestEntities__Id__%\'
AND T.Name = \'TestEntities\'
DECLARE @Sql NVARCHAR(2000) = \'ALTER TABLE TestEntities DROP Constraint \' + @Name
EXEC sp_executesql @Sql
ALTER TABLE TestEntities
ADD CONSTRAINT IdDef DEFAULT NEWSEQUENTIALID() FOR Id\");
}
}
public class TestEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Context : DbContext
{
public DbSet<TestEntity> TestEntities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TestEntity>()
.Property(e => e.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
,为什么还要担心数据库中Guid列的默认值?为什么不像其他任何值一样在客户端上生成Guid。这要求您的客户端代码中有一个方法,该方法将生成类似于COMB的Guid:
public static Guid NewGuid()
{
var guidBinary = new byte[16];
Array.Copy( Guid.NewGuid().ToByteArray(),guidBinary,8 );
Array.Copy( BitConverter.GetBytes( DateTime.Now.Ticks ),8,8 );
return new Guid( guidBinary );
}
Guid的优点之一是,您可以在客户端上生成它们而无需往返数据库。
,最简单的答案
public class User
{
public User(Guid? id = null,DateTime? created = null)
{
if (id != null)
Id = id;
if (created != null)
Created = created;
}
public User()
{
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime? Created { get; internal set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid? Id { get; internal set; }
}
假设您已将数据库表设置为默认值ѭ4,在我的情况下,该表由FluentMigrator迁移管理。