自动生成不是Entity Framework中主键的GUID列

时间:2014-10-14 21:21:38

标签: c# sql sql-server entity-framework

我从现有的模型和数据库迁移到Entity Framework。在该数据库中,有几个表具有GUID列,这些表不是主键(或根本不是键!)。每个表都有一个ID列。 GUID列具有在其上定义的ROWGUIDCOL属性,以及DEFAULT(newid())。

现在,当我插入数据库时​​,我会为此列获取所有零。

我尝试过使用数据注释:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Guid {get; set;}

这个问题是它丢弃了我的ID列上的identity属性(并给了我插入错误)。除此之外,我注意到对于以下迁移,EF实际上为上下方法生成了相同的SQL:

public override void Up()
{

    AlterColumn("dbo.Client", "Guid", c => c.Guid(nullable: false, identity: true));
}

public override void Down()
{
    AlterColumn("dbo.Client", "Guid", c => c.Guid(nullable: false));
}

使用生成的sql:

ALTER TABLE [dbo].[Client] ALTER COLUMN [Guid] [uniqueidentifier] NOT NULL

为什么上面的迁移会为两个语句创建相同的sql?如何让EF生成GUID?我可以/必须在客户端(代码)空间中执行此操作吗?如果必须,我怎样才能保证表格之间的唯一性?

2 个答案:

答案 0 :(得分:2)

DatabaseGenerationOption.Identity应该用于标识列。

请尝试使用DatabaseGenerationOption.Computed。它应该阻止EF在插入列时发送值,它应该在SaveChanges上正确地提取db生成的值。

答案 1 :(得分:1)

尝试将预先存在的ID ident列转换为GUID时,我遇到了一些错误。计算不起作用,设置为身份不起作用。设置为DatabaseGeneratedOption.None会导致错误,指出我无法在必填字段中插入空值。我的构造函数中有一个NewGuid代,但这似乎也没有帮助。

为了让它工作,我删除了我的Migration .cs文件和我的数据库,然后使用dataannotations,我能够通过将新的GUID ID设置为Key,DatabaseGeneratedOption.None然后放置支持字段来打败系统ID属性。这迫使我的Getter查看私有字段,确定它是否为Guid.Empty,如果是,则为我生成一个新的GUID。

    private Guid id = Guid.Empty;

    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    [HiddenInput(DisplayValue = false)]
    public Guid CompanyId
    {
        get
        {
            if(id==Guid.Empty)
                id = new Guid();
            return id;
        }
        set { id = value; }
    }