Ho un database funzionante e sto usando EntityFramework per manipolare i suoi dati. Ho finito con DbSet<Type>
e DbContext
e ho bisogno di un modo per recuperare qualsiasi chiave esterna nel tipo anonimo usando qualsiasi modo disponibile
Codice Esempio di classi EF generate automaticamente
public partial class Country
{
public int ID { get; private set; } //primaryKey
public ICollection<City> Cities { get; set; }
}
public partial class City
{
public int City_ID { get; private set; } //primaryKey
public int Country_ID { get; private set; } //ForeignKey Needed To get For Any Entity or Class
public Country Country { get; set; }
}
DbContext Child generato automaticamente
public partial class Entities : DbContext
{
public virtual DbSet<Country> Countries { get; set; }
public virtual DbSet<City> Cities { get; set; }
}
Devo ottenere tutte le chiavi esterne come Country_ID
da DbSet<{UnknownType}>
Questo ti darà un dizionario con tutte le proprietà di navigazione come Chiave e tutte le proprietà correlate come Valore (il valore potrebbe essere una proprietà dall'altra entità)
Aggiungi questi alla tua classe DBContext e chiama db.GetForeignKeyProperties<Person>()
Il risultato sarà qualcosa del tipo:
"Indirizzo" - "ID indirizzo"
"Boss" - "Person.BossID"
public Dictionary<string,string> GetForeignKeyProperties<DBType>()
{
EntityType table = GetTableEntityType<DBType>();
Dictionary<string, string> foreignKeys = new Dictionary<string, string>();
foreach (NavigationProperty np in table.NavigationProperties)
{
var association = (np.ToEndMember.DeclaringType as AssociationType);
var constraint = association.ReferentialConstraints.FirstOrDefault();
if (constraint != null && constraint.ToRole.GetEntityType() == table)
foreignKeys.Add(np.Name, constraint.ToProperties.First().Name);
if (constraint != null && constraint.FromRole.GetEntityType() == table)
foreignKeys.Add(np.Name, constraint.ToProperties.First().DeclaringType.Name+"."+constraint.ToProperties.First().Name);
}
return foreignKeys;
}
private EntityType GetTableEntityType<DBType>()
{
return GetTableEntityType(typeof(DBType));
}
private EntityType GetTableEntityType(Type DBType)
{
ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext;
MetadataWorkspace workspace = objContext.MetadataWorkspace;
EntityType table = workspace.GetEdmSpaceType((StructuralType)workspace.GetItem<EntityType>(DBType.FullName, DataSpace.OSpace)) as EntityType;
return table;
}
Ecco un metodo che restituisce i valori chiave degli oggetti entità noti:
IEnumerable<IDictionary<string,object>> GetKeyValues<T>(DbContext db,
IEnumerable<T> entities)
where T : class
{
var oc = ((IObjectContextAdapter)db).ObjectContext;
return entities.Select (e => oc.ObjectStateManager.GetObjectStateEntry(e))
.Select(objectStateEntry => objectStateEntry.EntityKey)
.Select(ek => ek.EntityKeyValues
.ToDictionary (x => x.Key, y => y.Value));
}
Questo metodo utilizza l'API ObjectContext
sottostante per ottenere oggetti ObjectStateEntry
che appartengono a ciascun oggetto entità. EntityKey
contiene i valori chiave di un'entità come coppia chiave-valore. (Le entità con chiavi composite hanno più di un valore chiave).