【问题标题】:Generate Guid on Serverside Entity Framework 5?在服务器端实体框架 5 上生成 Guid?
【发布时间】:2013-04-30 19:35:56
【问题描述】:

我来自休眠背景,我想知道如何在服务器端自动生成 Guid,而不是在数据库端进行往返?

在流畅的nhibernate中它很简单

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

【问题讨论】:

    标签: entity-framework guid


    【解决方案1】:

    如果您想在服务器上生成密钥,只需在代码中执行此操作:

    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 中,他们不建议生成 db。
    • 啊,不知道 COMB 的区别。用更多选项更新了答案。
    • 注意,如果您从 edmx 生成,请确保将 Store Generated Column 设置为 Identity您希望 GUId 由服务器生成的列。
    • 对于 EF fluent API,请参阅:dailywebtips.blogspot.com/2012/09/…
    【解决方案2】:

    此代码可以满足您的需要:

    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 制作了一个 forloop,并将它传递给 Guidcomb 方法,它不断生成相同的 Guid。所以不确定是否真的会生成新的。
    • @chobo2 我不知道代码不能更改扩展方法中传入的对象。我已经更新了代码。
    • 嘿,当我使用你的代码时,它似乎改变了 GUID,但如果你只制作 3 个空对象并检查 ID,它们都是一样的。
    • @chobo2 它们应该几乎相同,因为它们是连续的,即相差一个字节。
    【解决方案3】:

    从 EF 6.1.3 开始,将 GUID 用作 PK 时,数据库默认值 [newsequentialid() 或 newid()] 可能很重要 见entity framework use a guid as the primary key。

    【讨论】:

      猜你喜欢
      • 2015-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 2023-03-26
      • 2020-08-05
      相关资源
      最近更新 更多