2013-04-30 3 views
9

Я прихожу с фона nhibernate, и мне интересно, как я могу автоматически генерировать Guid на стороне Serer и не совершать туда и обратно, чтобы сделать это на стороне базы данных?Создать руководство по структурной структуре серверов 5?

В Fluent NHibernate просто просто

Id(x => x.Id).GeneratedBy.GuidComb(); 

ответ

15

Если вы хотите, чтобы сгенерировать ключ на сервере, просто сделать это в коде:

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

Если вы после использования sequ а затем нет простого ответа на данный момент. Некоторые примеры, которые получают вас по верному пути:

+0

В Nhibernate у них есть GuidComb, что, мол, лучше. Не имеет значения с EF? Любое преимущество между двумя способами в EF. В nhibernate они не рекомендуют делать db. – chobo2

+0

Ах, не знал о различии COMB. Обновлен ответ с некоторыми дополнительными параметрами. – Richard

+2

Обратите внимание, что если вы создаете из ** edmx **, убедитесь, что в ** Store Generated Column ** установлено значение ** Identity ** для столбца, который должен быть создан сервером GUID. –

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

Test класс:

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")); 
    } 
+0

hmm не следует этому. Я делаю forloop с нулевым GUID и передал его в метод Guidcomb, и он продолжает генерировать тот же Guid. Поэтому не уверен, действительно ли генерирует новые. – chobo2

+0

@ chobo2 Я не знал, что код не может изменить переданный объект в методе расширения. Я обновил код. – qujck

+0

Эй, когда я использую ваш код, он, похоже, меняет GUID, но если вы просто делаете 3 пустых объекта и проверяете ID, то они все одинаковы. – chobo2

-1

Как ФВ 6.1.3, по умолчанию базы данных [newsequentialid() или newid()] может иметь важное значение при использовании GUID в качестве PK-х См entity framework use a guid as the primary key.

Смежные вопросы