Entity Framework Guid

2020-07-06 03:54发布

问题:

I'm trying to setup the Entity Framework with SQL Server 2008. I'm using Guids for the keys on my tables. Is there a way to set it up so the keys are automatically generated by the database? I tried setting "RowGuid" to true and also set the column's default value to be "(newid())". Either way the mapped class still needs me to give it a Guid on the C# side. Any ideas?

回答1:

Not yet:

17.4.Can I use a server-generated guid as my entity key?

Unfortunately, in v1 of the EF this is not supported. While it is possible with SQL Server to have a column of type “uniqueidentifier” and to set it’s default value to be “newid()”, with SQL Server 2000 there’s no good way to extract the value that the server generated at the time you do the insert. This can be done on more recent versions of SQL Server, though, so the intent is that we should find a clean way to special case this support in future versions of the EF so it can be supported on those databases that allow it and not on others. For now, the work around is to generate the guid on the client (ideally in the constructor of your object) rather than on the server.



回答2:

Personally, I think that anyone who is using EF would be willing to give up compatibility with SQL Server 2000 to get the features they need. It seems like every halfway non-trivial thing that I need to do in EF is unsupported due to the fact that they have to keep compatibility with SQL Server 2000.

When will it ever end!



回答3:

Since a Guid is a structure, a null value is never passed so the defaults don't kick in. You could consider a nullable Guid: Guid?, though this may cause headaches as mentioned in this post:

Nullable GUID

I found it easier to just initialize the Guid with a new value:

private Guid _identifier = Guid.NewGuid();

If it's an existing record, it will be replaced when the object is populated. If not, the initialized value will be inserted.



回答4:

Easier with v4.

A better way than having to change the edmx is the bit I have below that will generate Guid's for you. It checks for primary key and reflects to set it.

Warnings - Assumes a single Guid primary key and that you are not setting it for some reason of your own.

void OgaraEntities_SavingChanges(object sender, EventArgs e)
{
  foreach (ObjectStateEntry entry in
      ((ObjectContext)sender).ObjectStateManager.GetObjectStateEntries(
      EntityState.Added ))
  {
    if (!entry.IsRelationship){
      string keyFieldName = entry.EntitySet.ElementType.KeyMembers[0].Name;
      object entity = entry.Entity;
      PropertyInfo pi = entity.GetType().GetProperty(keyFieldName);
      pi.SetValue(entity, Guid.NewGuid(), null);
    }
  }      
}


回答5:

Update: Microsoft has fixed this bug for VS2010 SP1 with hotfix KB2561001.



回答6:

How about static method in partial class??

public partial class SomeEntity
{
     public static SomeEntity Create()
     {
         return new SomeEntity() { Id = Guid.NewGuid(); }
     }
}