2011-05-23 16 views
8

में GUID COMB रणनीति कोडफर्स्ट डिज़ाइन का उपयोग करके नई इकाई फ्रेमवर्क 4.1 में ऑब्जेक्ट्स के लिए ग्विड COMB पहचान रणनीति को लागू करने का कोई तरीका है? मैंने सोचा कि StoreGeneratedPattern सेटिंग काम करेगा, लेकिन यह अभी भी मुझे सामान्य GUID देता है।ईएफ

+0

मुझे लगता है कि आप पहले से ही डीबी-सर्वर-साइड डिफ़ॉल्ट जांच चुके हैं? –

+0

हाँ, मेरे पास है। मुझे अपनी समस्या का समाधान करने के लिए यह नहीं मिला। – Ciel

उत्तर

8

मुझे लगता है कि आप SQL सर्वर का उपयोग अपने डेटाबेस के रूप में कर रहे हैं। यह विभिन्न एमएस उपकरणों के बीच असंगतता का एक अच्छा उदाहरण है। SQL सर्वर टीम newid() का उपयोग UNIQUEIDENTIFIER कॉलम के लिए डिफ़ॉल्ट मान के रूप में करने की अनुशंसा नहीं करती है और ADO.NET टीम इसका उपयोग करती है यदि आप Guid संपत्ति को डेटाबेस में स्वत: उत्पन्न करने के रूप में निर्दिष्ट करते हैं। उन्हें इसके बजाय newsequentialid() का उपयोग करना चाहिए!

यदि आप डेटाबेस द्वारा जेनरेट किए गए अनुक्रमिक गइड्स चाहते हैं तो आपको जेनरेट टेबल को संशोधित करना होगा और यह वास्तव में जटिल है क्योंकि आपको स्वत: जेनरेट की गई डिफ़ॉल्ट बाधा मिलनी चाहिए, इसे छोड़ दें और नई बाधा बनाएं। यह सब कस्टम डेटाबेस प्रारंभकर्ता में किया जा सकता है। यहां आपके पास मेरा नमूना कोड है:

class Program 
{ 

    static void Main(string[] args) 
    { 
     Database.SetInitializer(new CustomInitializer()); 
     using (var context = new Context()) 
     { 
      context.TestEntities.Add(new TestEntity() { Name = "A" }); 
      context.TestEntities.Add(new TestEntity() { Name = "B" }); 
      context.SaveChanges(); 
     } 
    } 
} 

public class CustomInitializer : DropCreateDatabaseAlways<Context> 
{ 
    protected override void Seed(Context context) 
    { 
     base.Seed(context); 

     context.Database.ExecuteSqlCommand(@" 
      DECLARE @Name VARCHAR(100) 

      SELECT @Name = O.Name FROM sys.objects AS O 
      INNER JOIN sys.tables AS T ON O.parent_object_id = T.object_id 
      WHERE O.type_desc LIKE 'DEFAULT_CONSTRAINT' 
       AND O.Name LIKE 'DF__TestEntities__Id__%' 
       AND T.Name = 'TestEntities' 

      DECLARE @Sql NVARCHAR(2000) = 'ALTER TABLE TestEntities DROP Constraint ' + @Name 

      EXEC sp_executesql @Sql 

      ALTER TABLE TestEntities 
      ADD CONSTRAINT IdDef DEFAULT NEWSEQUENTIALID() FOR Id"); 
    } 
} 

public class TestEntity 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

public class Context : DbContext 
{ 
    public DbSet<TestEntity> TestEntities { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<TestEntity>() 
      .Property(e => e.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
    } 
} 
+0

यह अनावश्यक लगता है। मैंने वास्तव में आशा की थी कि 4.1 ईएफ इससे अधिक मजबूत होगा। मेरे लिए इसे साफ़ करने के लिए बहुत बहुत धन्यवाद, यह पूरी तरह से काम किया। – Ciel

+1

मैं दृढ़ता से बीज विधि में इस तरह की चीजें नहीं करने की सलाह दूंगा। इसके बजाय यह एक अलग प्रवासन में आता है। हर बार माइग्रेशन ट्रिगर होने पर बीज बुलाया जाएगा। यह नहीं कह रहा कि यह सही समाधान नहीं है, बस यह गलत जगह पर ट्रिगर किया गया है। –

+2

@CasperLeonNielsen: ईएफ माइग्रेशन एपीआई मिलने से पहले मैंने इस उदाहरण को लंबे समय से लिखा था। आप इसे अद्यतित करने के लिए माइग्रेशन के साथ एक नया उत्तर जोड़ सकते हैं। –

14

डेटाबेस में ग्रिड कॉलम के लिए डिफ़ॉल्ट के बारे में चिंता क्यों करें? क्लाइंट पर किसी भी अन्य मूल्य की तरह क्यों न केवल ग्रिड उत्पन्न करें। यही कारण है कि आवश्यकता है आप अपने ग्राहक कोड में एक विधि है COMB की तरह guids उत्पन्न करेगा:

public static Guid NewGuid() 
{ 
    var guidBinary = new byte[16]; 
    Array.Copy(Guid.NewGuid().ToByteArray(), 0, guidBinary, 0, 8); 
    Array.Copy(BitConverter.GetBytes(DateTime.Now.Ticks), 0, guidBinary, 8, 8); 
    return new Guid(guidBinary); 
} 

Guid के लाभों में से एक विशेष रूप से है कि आप डेटाबेस के लिए एक राउंड ट्रिप के बिना ग्राहक पर उन्हें उत्पन्न कर सकते हैं।

+2

+1 यदि GUID की तरह COMB को परिभाषित करना इतना आसान है तो आप इस कोड को इसके साथ जोड़ सकते हैं: http://stackoverflow.com/questions/5275306/does-entity-framework-4-code-first-have-support-for-identity -जेनरेटर-जैसी-निब/5277642 # 5277642 और आपको guid.comb प्रारंभकर्ता मिल जाता है। –

+0

मुझे दो उत्तरों के बीच एक कठिन समय चुनना पड़ा, क्योंकि दोनों अनिवार्य रूप से एक ही परिणाम के लिए नेतृत्व किया। वे दोनों उपयोगी हैं। इस जानकारी के लिए बहुत बहुत धन्यवाद, यह बहुत अच्छी तरह से काम करता है। – Ciel

+0

अनुक्रमिक रूप से जेनरेट किए गए मार्गदर्शकों का उपयोग करने से SQL सर्वर में अनुक्रमण कम हो रहा है। –

2

सरल जवाब

public class User 
{ 
    public User(Guid? id = null, DateTime? created = null) 
    { 
     if (id != null) 
      Id = id; 

     if (created != null) 
      Created = created; 
    } 

    public User() 
    { 
    } 

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public DateTime? Created { get; internal set; } 

    [Key] 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid? Id { get; internal set; } 
} 

इसका मतलब यह है कि आप newsequentialid() के डिफ़ॉल्ट जो मेरे मामले में FluentMigrator माइग्रेशन द्वारा किया जाता है के साथ सेट अपने डेटाबेस तालिका है।

+1

इसके लिए दूसरों की सहायता करने के लिए, इसे "फ़्लुएंट माइग्रेटर माइग्रेशन" –

+1

@CasperLeonNielsen का एक उदाहरण चाहिए जो वास्तव में सच नहीं है, इसके लिए टेबल स्कीमा को डिफ़ॉल्ट सेट होना आवश्यक है। आप 'newsequentialid()' का डिफ़ॉल्ट सेट कैसे करते हैं, वास्तव में इस प्रश्न के दायरे से बाहर है और एक सामान्य एसक्यूएल स्कीमा चिंता बन जाता है। –

+0

http://stackoverflow.com/questions/12257465/update-row-data-with-a-new-value-per-row-using-fluentmigrator –