Entity Framework: valorizzare automaticamente i campi Identity di tipo Guid
Continuando sulla scia del post precedente Entity Framework: salvare automaticamente la data di ultima modifica, in questo gestisco la valorizzazione, ad ogni salvataggio di nuovi oggetti, dei campi identity di tipo Guid. Questi campi non sono gestiti correttamente da Entity Framework 4. Infatti, impostanto al proprietà StoreGeneratedPattern al valore Identity, questa non viene gestita correttamente con il risultato che viene sempre salvato sul database un Guid vuoto (empty).
Per aggirare il problema è sufficiente gestire l'evento SavingChanges del contesto.
In pratica ciclo su tutti gli aggetti aggiunti e, se trovo una proprietà con l'attributo StoreGeneratedPattern=Identity, di tipo Guid, non ancora valorizzato (Guid.Empty), la setto con un nuovo un nuovo Guid.
I campi identity funzionano bene quando il tipo di dato è di tipo intero. Con i Guid, il problema è nell'attributo Identity in quanto non viene riportato sull'xml di mapping del database. Speriamo venga risolto nei prossimi service pack
Per aggirare il problema è sufficiente gestire l'evento SavingChanges del contesto.
In pratica ciclo su tutti gli aggetti aggiunti e, se trovo una proprietà con l'attributo StoreGeneratedPattern=Identity, di tipo Guid, non ancora valorizzato (Guid.Empty), la setto con un nuovo un nuovo Guid.
C#: Sgart_Entities_Extension.cs
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data.EntityClient;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Runtime.Serialization;
namespace CrmSystem.Data
{
public partial class Sgart_Entities
{
private const string PIDENTITY = "http://schemas.microsoft.com/ado/2009/02/edm/annotation:StoreGeneratedPattern";
partial void OnContextCreated()
{
this.SavingChanges += new EventHandler(Internal_SavingChanges);
}
private void Internal_SavingChanges(object sender, EventArgs e)
{
ObjectContext context = (ObjectContext)sender;
IEnumerable<ObjectStateEntry> changes = context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added);
foreach (ObjectStateEntry entry in changes)
{
CurrentValueRecord records = entry.CurrentValues;
for (int i = 0; i < records.FieldCount; i++)
{
if (records.IsDBNull(i) == false && typeof(Guid).Equals(records.GetFieldType(i)))
{
if (records.GetGuid(i) == Guid.Empty)
{
System.Data.Metadata.Edm.MetadataProperty identity = null;
bool ok = records.DataRecordInfo.FieldMetadata[i].FieldType.MetadataProperties.TryGetValue(PIDENTITY, false, out identity);
if (ok && identity.Value.ToString() == "Identity")
{
records.SetGuid(i, Guid.NewGuid());
}
}
}
}
}
}
}
}