I have a working data base and i am using EntityFramework to manipulate its data. I ended with having DbSet<Type>
and DbContext
and I need a way to retrieve any foreign key in the anonymous type using any available way
Code Example of auto generated EF classes
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; }
}
Auto Generated DbContext Child
public partial class Entities : DbContext
{
public virtual DbSet<Country> Countries { get; set; }
public virtual DbSet<City> Cities { get; set; }
}
I need to get all foreignKeys like Country_ID
from DbSet<{UnknownType}>
This will give you a dictionary with all navigation properties as Key and all related properties as Value (the value might be a property from the other entity)
Add these to your DBContext class and call db.GetForeignKeyProperties<Person>()
The result will be something like:
"Address" - "AddressID"
"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;
}
Here's a method that returns key values of know entity objects:
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));
}
This method uses the underlying ObjectContext
API to obtain ObjectStateEntry
objects that belong to each entity object. The EntityKey
contains the key value(s) of an entity as a key-value pair. (Entities with composite keys have more than one key value.)