سؤال

هل هناك أي طريقة لتنفيذ إستراتيجية هوية Guid COMB للكائنات في Entity Framework 4.1 الجديد باستخدام تصميم CodeFirst؟اعتقدت وضع StoreGeneratedPattern ستعمل، لكنها لا تزال تعطيني المعرفات الفريدة العمومية (GUIDs) العادية.

هل كانت مفيدة؟

المحلول

أعتقد أنك تستخدم خادم SQL كقاعدة بيانات خاصة بك.هذا مثال جيد على عدم الاتساق بين أدوات MS المختلفة.لا يوصي فريق خادم 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);
    }
}

نصائح أخرى

لماذا تقلق بشأن الإعدادات الافتراضية لأعمدة GUID في قاعدة البيانات على الإطلاق؟لماذا لا تولد فقط GUID على العميل مثل أي قيمة أخرى.يتطلب ذلك لديك طريقة في رمز العميل الخاص بك والتي ستولد GUIDS مشط:

giveacodicetagpre.

واحدة من مزايا GUID هي على وجه التحديد أنه يمكنك توليدها على العميل دون رحلة ذهابا وإيابا إلى قاعدة البيانات.

أبسط إجابة

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top