在服务器端使用Entity Framework 5生成Guid?

9

我来自于一个 nhibernate 背景,想知道如何在服务器端自动生成 Guid,而不必在数据库端进行往返操作?

在 fluent nhibernate 中,只需简单地执行以下操作:

   Id(x => x.Id).GeneratedBy.GuidComb();
3个回答

18
如果您想在服务器上生成密钥,只需按以下代码操作即可:
public class TestObject 
{
    public TestObject() 
    {
        Id = Guid.NewGuid();
    }
    public Guid Id { get; set; }
}
如果你希望数据库生成密钥,则可以使用DatabaseGenerated 属性:
public class TestObject 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
}

如果你想使用连续的GUID,那么目前没有简单的答案。以下是一些能够指导你正确方向的示例:


在NHibernate中,他们有GuidComb,据说更好。这对于EF来说无关紧要吗?在EF的两种方式之间有什么优势。在NHibernate中,他们不建议进行数据库生成。 - chobo2
啊,不知道 COMB 的区别。现在更新了答案,并提供了更多的选项。 - Richard
3
请注意,如果您是从 edmx 生成代码,请确保将要生成 GUid 的列的 Store Generated Column 设置为 Identity,以便服务器自动生成。 - Mohamed Mansour
有关EF流畅API,请参见此链接:http://dailywebtips.blogspot.com/2012/09/entity-framework-5-auto-generated-guid.html - Masood Khaari

1
这段代码可以满足您的需求:
using System;
using System.Runtime.InteropServices;
public static class SequentialGuidProvider
{
    [DllImport("rpcrt4.dll", SetLastError = true)]
    private static extern int UuidCreateSequential(out Guid guid);

    private static Guid CreateGuid()
    {
        Guid guid;
        int result = UuidCreateSequential(out guid);
        if (result == 0)
            return guid;
        else
            return Guid.NewGuid();
    }

    public static Guid GuidComb(this Nullable<Guid> guid)
    {
        if (!guid.HasValue) guid = SequentialGuidProvider.CreateGuid();
        return guid.Value;
    }
}

测试类:

public class TestObject
{
    public TestObject()
    {
    }

    private Nullable<Guid> _guid = null;
    public Guid Id
    {
        get
        {
            _guid = _guid.GuidComb();
            return _guid.Value();
        }
        set
        {
            _guid = value;
        }
    }
}

测试代码:

    static void Main(string[] args)
    {
        TestObject testObject1 = new TestObject();
        TestObject testObject2 = new TestObject();
        TestObject testObject3 = new TestObject();
        //simulate EF setting the Id
        testObject3.Id = new Guid("ef2bb608-b3c4-11e2-8d9e-00262df6f594");

        //same object same id
        bool test1 = testObject1.Id == testObject1.Id;
        //different object different id
        bool test2 = testObject1.Id != testObject2.Id;
        //EF loaded object has the expected id
        bool test3 = testObject3.Id.Equals(new Guid("ef2bb608-b3c4-11e2-8d9e-00262df6f594"));
    }

我不太明白这个。我用一个可空的 GUID 做了一个 for 循环,并将其传递到 Guidcomb 方法中,但它一直生成相同的 GUID。所以我不确定它是否实际上生成了新的 GUID。 - chobo2
@chobo2 我不知道代码不能在扩展方法中更改传入的对象。我已经更新了代码。 - qujck
嘿,当我使用你的代码时,似乎会更改GUID,但如果你只创建3个空对象并检查ID,它们都是相同的。 - chobo2
@chobo2 他们应该几乎相同,因为它们是连续的,即只相差一个字节。 - qujck

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接