9

I am coming from a nhibernate background and I am wondering how can I generate the Guid automatically on the serer side and not make a round trip to make it on the database side?

In fluent nhibernate it is simple just

   Id(x => x.Id).GeneratedBy.GuidComb();
chobo2
  • 83,322
  • 195
  • 530
  • 832

3 Answers3

18

If you want to generate the key on the server, simply do this in code:

public class TestObject 
{
    public TestObject() 
    {
        Id = Guid.NewGuid();
    }
    public Guid Id { get; set; }
}

If you want the database to generate the key, then use the DatabaseGenerated attribute:

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

If you're after using sequential GUIDs, then there's no easy answer at the moment. Some examples which get you along the right road:

Community
  • 1
  • 1
Richard
  • 29,854
  • 11
  • 77
  • 120
  • In Nhibernate they have GuidComb what is supposedly better. Does it not matter with with EF? Any advantage between the 2 ways in EF. In nhibernate they don't recommend to do db generated. – chobo2 May 01 '13 at 01:58
  • Ah, wasn't aware of the COMB difference. Updated the answer with some more options. – Richard May 01 '13 at 10:05
  • 3
    Note, if you are generating from the **edmx**, make sure the **Store Generated Column** is set to **Identity** for the column you want GUid to be server generated. – Mohamed Mansour Jun 21 '13 at 04:31
  • For EF fluent API see this: http://dailywebtips.blogspot.com/2012/09/entity-framework-5-auto-generated-guid.html – Masood Khaari Jun 14 '14 at 10:43
1

This code does what you need:

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

Test class:

public class TestObject
{
    public TestObject()
    {
    }

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

Test code:

    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"));
    }
qujck
  • 14,388
  • 4
  • 45
  • 74
  • hmm not following this. I make a forloop with a nullable GUID and passed it into the Guidcomb method and it keeps generating the same Guid. So not sure if actually generates new ones. – chobo2 May 02 '13 at 22:01
  • @chobo2 I didn't know that the code can't changed the passed in object within the extension method. I've updated the code. – qujck May 03 '13 at 08:07
  • Hey, when I use your code it seems to change the GUID but if you just make 3 empty objects and check the ID they are all the same. – chobo2 May 03 '13 at 16:13
  • @chobo2 they should be almost identical because they are sequential, i.e. different by one byte. – qujck May 03 '13 at 16:25
-1

As of EF 6.1.3, database defaults [newsequentialid() or newid()] may be important when using GUID's as PK's See entity framework use a guid as the primary key.

David Greydanus
  • 2,551
  • 1
  • 23
  • 42