如何在代码中首先或使用ColumnBuilder将ROWGUIDCOL属性指定为Guid类型列?

时间:2013-06-26 11:53:57

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

考虑这个迁移代码:

       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中的等效代码是什么?解决方案是什么?

感谢。

3 个答案:

答案 0 :(得分:3)

似乎不能通过Entity Framework直接设置ROWGUIDCOL属性,但可能可以通过创建" creative"将属性注入到生成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()
)

" UNIQUE"要求是通过由第二个参数创建的唯一索引来完成的,其中" true"在Index()方法中。

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

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:0)

我想您想为具有[Test("BlockCopy", "", true)] public double[] Test1(double[,] input, int scale) { var width = input.GetLength(0); var height = input.GetLength(1); var size = width * height; var result = new double[size]; Buffer.BlockCopy(input, 0, result, 0, size * sizeof(double)); return result; } [Test("MarshalCopy", "", false)] public unsafe double[] Test2(double[,] input, int scale) { var width = input.GetLength(0); var height = input.GetLength(1); var size = width * height; var result = new double[size]; fixed (double* pInput = input) Marshal.Copy((IntPtr)pInput, result, 0, size ); return result; } [Test("ElemCopy", "", false)] public double[] Test3(double[,] input, int scale) { var width = input.GetLength(0); var height = input.GetLength(1); var size = width * height; var result = new double[size]; for (var i = 0; i < width; i++) for (var j = 0; j < height; j++) result[i * height + j] = input[i,j]; return result; } [Test("ElemCopy Unsafe", "", false)] unsafe public double[] Test4(double[,] input, int scale) { var width = input.GetLength(0); var height = input.GetLength(1); var size = width * height; var result = new double[size]; fixed (double* pInput = input, pResult = result) for (var i = 0; i < width; i++) for (var j = 0; j < height; j++) *(pResult + i * height + j) = *(pInput + i * height + j); return result; } [Test("memcpy", "", false)] unsafe public double[] Test5(double[,] input, int scale) { var width = input.GetLength(0); var height = input.GetLength(1); var size = width * height; var result = new double[size]; fixed (double* pInput = input, pResult = result) memcpy((IntPtr)pResult, (IntPtr)pInput, (UIntPtr)(size * sizeof(double))); return result; } [Test("Linq", "", false)] unsafe public double[] Test6(double[,] input, int scale) { return input.OfType<double>().ToArray(); } 列的表使用此功能。使用EntityTypeConfiguration提示EF使其可以生成正确的脚本,并且不需要您手动对其进行编辑(EF Core 2.2)。

使用此示例实体:

FILESTREAM

此配置:

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

EF生成正确的迁移脚本:

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);
    }
}