【问题标题】:How can specify ROWGUIDCOL property to Guid type column in code first or with ColumnBuilder?如何首先在代码中或使用 ColumnBuilder 将 ROWGUIDCOL 属性指定为 Guid 类型列?
【发布时间】:2013-06-23 13:06:22
【问题描述】:

考虑这个迁移代码:

       CreateTable(
            "dbo.Document",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Doc = c.String(),
                    RowGuid = c.Guid(nullable: false),
                    Person_Id = c.Int(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Person", t => t.Person_Id)
            .Index(t => t.Person_Id);

我希望RowGuidROWGUIDCOL,并像这样定义(SQL):

 [RowGuid] [UNIQUEIDENTIFIER] not null RowGuidCol Unique default newid()

EntityFramework/CodeFirst 中的等效代码是什么?解决办法是什么?

谢谢。

【问题讨论】:

  • 有人对此有解决方案吗?我在这个问题上被阻止了。
  • 顺便说一句 .. rowguidcol 是做什么的?
  • @vishalsharma,转到以下链接并向下滚动以阅读 Clifford Dibble 的回答:social.msdn.microsoft.com/Forums/sqlserver/en-US/… 本质上它只是标记列,以便可以通过 $ROWGUID 对其进行一般引用。

标签: c# .net sql-server entity-framework ef-code-first


【解决方案1】:

看起来 ROWGUIDCOL 属性不能直接通过实体框架设置,但可能可以通过“创造性”将属性注入生成 SQL ;-) storeType 参数(假设 storeType 真正允许您覆盖默认数据类型)。从原始问题的代码开始,尝试以下操作:

 CreateTable(
            "dbo.Document",
            c => new
                {
                    RowGuid = c.Guid(nullable: false, identity: true,  
                                     defaultValueSql: "newid()",
                                     storeType: "UNIQUEIDENTIFIER ROWGUIDCOL"),
                    Person_Id = c.Int()
                })
            .Index(t => t.RowGuid, true);

很遗憾,我没有办法对此进行测试,但鉴于以下 SQL 有效,我认为值得一试:

CREATE TABLE dbo.Test1
(
    Col1 INT NOT NULL,
    Col2 UNIQUEIDENTIFIER ROWGUIDCOL NOT NULL UNIQUE DEFAULT NEWID()
)

“唯一”要求是通过 Index() 方法中的第二个参数为“true”创建的唯一索引来实现的。

请注意,如果表已经有一个标有 IDENTITY 的列,则在 Guid() 方法中使用“identity: true”可能会出现一些问题。我发现了解决这种情况的相关问题:Entity Framework Code First Using Guid as Identity with another Identity Column

【讨论】:

  • 这不起作用。它产生“列、参数或变量 #4:找不到数据类型 UNIQUEIDENTIFIER ROWGUIDCOL。”
  • @DanielHilgarth 奇数。较新版本的 EF 是否有可能进行 O.P. 使用的版本中不存在的验证?这个问题和答案已有 3 年历史了,所以可能发生了一些变化?你用的是什么版本,仅供参考?
  • 可能,是的。我正在使用 EF6
  • 是的,它有效。但在网络核心你应该写“类型”而不是“商店类型”
【解决方案2】:

经过一番研究和四处询问,我认为这是不可能的。我在代码中解决它的方法是在新建对象时获取新的 GUID:

    public class MyPOCO {
           public MyPOCO() { 
                RowGuid = Guid.NewGuid();
           }
      //.....
   }

这样,当我向表中插入新行时,我总是会生成一个新的 GUID。我想念使用 ROWGUIDCOL 但 EF 确实让我的生活变得简单。

【讨论】:

  • 由于 guid 碎片问题,这可能是个坏主意。您希望它在 mssql 服务器中使用 NEWSEQUENTIALID(),如果您将其设置为标识 ([DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]),它将执行此操作。幸运的是,您可以只使用迁移: Sql("ALTER TABLE mytable ALTER COLUMN mycolumn ADD ROWGUIDCOL");
【解决方案3】:

我想你想要一个带有FILESTREAM 列的表。使用 EntityTypeConfiguration 提示 EF 可以生成正确的脚本,并且不需要您手动编辑它(EF Core 2.2)。

以这个样本实体为例:

public class FileEntity
{
    public Guid FileGuid { get; private set; }
    public byte[] Document { get; private set; }
}

还有这个配置:

public class FileEntityConfiguration : IEntityTypeConfiguration<FileEntity>
{
    public void Configure(EntityTypeBuilder<FileEntity> builder)
    {
        builder
            .Property(m => m.Document)
            .HasColumnType("VARBINARY(MAX) FILESTREAM");

        builder
            .Property(m => m.FileGuid)
            .HasColumnType("UNIQUEIDENTIFIER ROWGUIDCOL")
            .IsRequired();

        builder
            .HasAlternateKey(m => m.FileGuid);
    }
}

EF 生成正确的迁移脚本:

FileGuid = table.Column<Guid>(type: "UNIQUEIDENTIFIER ROWGUIDCOL", nullable: false),
Document = table.Column<byte[]>(type: "VARBINARY(MAX) FILESTREAM", nullable: true)

【讨论】:

  • 我的数据库中未启用 FileStream,我通过 SQLCommand 以编程方式运行查询以在部署数据库后启用 FileStream。我已经添加了对 OnModelCreating 的更改,以根据您的帖子添加 FileStream 属性。但是,就我而言,没有创建具有 FileStream 属性的表,我认为这是因为在部署数据库时我没有启用 FileStream。我该如何解决我的问题?
  • @user1579234,在这种情况下,我会添加一个在创建数据库后运行的初始迁移脚本以启用 FileStream。
猜你喜欢
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2011-06-12
  • 1970-01-01
相关资源
最近更新 更多