Has anyone tried to use the GUID as primary key

Topics: Core, General, Writing modules
May 23, 2012 at 12:15 PM

 

I have tried to configure a new data table that are using Guid as the primary key.

But I'm not sure how to write it inside orchard. are there a standard way of doing this ?!

I think that everything that I try is failing some how 

 

 

Thanks Peter

Coordinator
May 23, 2012 at 5:55 PM

Not sure if you will succeed, as the default mapping is linked to an auto generated integer. Some more info here: http://stackoverflow.com/questions/7840250/orchard-custom-module-model-being-picked-up-by-nhibernate-requiring-virtual/7856337#7856337

And here: Orchard.Environment.ShellBuilders.CompositionStrategy.IsRecord()

May 25, 2012 at 9:40 AM
Edited May 25, 2012 at 9:43 AM

(sorry for the formatting. I keep running into formatting issues when I insert codesnippets into codeplex lately)

I have had to implement this because I wanted a set of table with their clustered indexes aligned to the Guid. I ran into struggles using an actual Guid column but I did succeed by using a string column as the primary key and building a Repository interface that uses a Guid.  I couldn't use IRepository though for this as it expects and int Id column, so I had to instead implement a special repository interface

 


 

 

public interface IGuidRepository<T> : IRepository<T>     {        T Get(Guid refId);    }

public class GuidRepository<T> : Repository<T>, IGuidRepository<T>   
{       
           public GuidRepository(ISessionLocator sessionLocator):base(sessionLocator)        {        }

           public virtual T Get(Guid refId)        {            return Session.Get<T>(refId.ToString());        }           

}


Then because it was a Generic I couldn't use IDependency, so I had to manually register it

using System.Reflection;

using Autofac;
using Orchard.Data.Providers;
using Module = Autofac.Module;

namespace SRB.Portal.Core.Storage.Models
{   
      public class GuidRepositoryModule : Module   
      {       
            protected override void Load(ContainerBuilder builder) {                            
                        builder.RegisterGeneric(typeof(GuidRepository<>)).As(typeof(IGuidRepository<>)).InstancePerDependency();       
            }   
      }
}


My models just implement "Id" as a string

 

public virtual string Id { get; set; } //RefId as a string       
public virtual DateTime StoredOn { get; set; }       
public virtual String LabelInternal { get; set; }       
public virtual String LabelExternal { get; set; }

And in my migrations file

 var value = table           
           .Column("Id", DbType.String, column => column.WithLength(40).PrimaryKey()) 
           .Column("StoredOn", DbType.DateTime)
           .Column("LabelInternal", DbType.String)
           .Column("LabelExternal", DbType.String);

 

And to use just inject it into your constructor and call Get(guid) on it.

 public ETIFObjectStorageService(IGuidRepository<T> repository)       
{           
       _Repository = repository;       
}

 

Hope this helps

May 30, 2012 at 6:35 AM

Thank you for your answers - very good help.

Ryang your example looks like what we need - thank you for sharing :-)

 

/Peter