Finding the related FK property of a Navigation Property
At run time I would like to find whether an EntityObject also has a foreign key property for a given NavigationProperty. I have this in two steps below. I imagine this is going to require some metadata querying.
I am unsure how to test whether a metadata class points to the type of a particular EntityObject type: ie I know conceptually but not programmically the relationship between an EntityType instance and an EntityObject instance.
So far I have:
/*puesdo code class representing edm example*/
class Possesion: EntityObject
{
//Nav prop
public Person Owner { get; set; }
//related FK prop
public int OwnerId { get; set; }
}
public static NavigationProperty GetNavigationProperty<TObjectContext, T>(
this ObjectContext context,
Expression<Func<T, Object>> targetProperty)
where TObjectContext : ObjectContext
{
//eg: possession => possession.Owner property type would be person
PropertyInfo targetProp = GetPropertyType(targetProperty);
//target type would be Possesion
Type targetType = targetProp.DeclaringType;
var containerName = context.DefaultContainerName;
var model = DataSpace.CSpace;
var workspace = context.MetadataWorkspace;
var container = workspace.GetEntityContainer(containerName, model);
EntitySetBase entitySet = container.BaseEntitySets
.Where(e => e.Name == context.GetEntitySetNameFromType(targetType))
.FirstOrDefault();
if (entitySet == null)
return null;
//materialize nav props for testing
var navigationProps = entitySet.ElementType.Members
.Where(m => m.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty
)
.Cast<NavigationProperty>()
.ToList();
//The question: how to filter the nav props for that which pertains
// to the target property?
NavigationProperty navProp = navigationProps
.Where(
//how do we select the nav property based on the Passed EntityObject's type
//ie how to we link the Metadata type to the concrete type??
n => n.FromEndMember.TypeUsage.???????? == targetProp.PropertyType)
.FirstOrDefault();
return navProp;
}
public static String GetPossibleFKPropertyName(Type entityObjectType, NavigationProperty property)
{
//Check each end for the target type
//with this end ie To or From, determine if there is a Property on the 开发者_如何学GoentityObject that equated to the PropertyRef column
//return this.
var toEnd = property.ToEndMember.GetEntityType();
//Again how do I determine that the Person metadata is a Person EntityObjectType?
if (toEnd.SomeTypeMember???? == entityObjectType)
return toEnd.KeyMembers[0].Name; //Testing HACK, return name for now.
var fromEnd = property.FromEndMember.GetEntityType();
if (fromEnd.SomeTypeMember???? == entityObjectType)
return fromEnd.KeyMembers[0].Name;
return "";
}
I ended up simply doing a text comparison on the FullName of the ElementType
ie:
n =>((RefType)n.ToEndMember.TypeUsage.EdmType).ElementType.FullName
== targetProp.PropertyType.FullName)
also the ToEnd being the property I am targeting then once I had the NavigationProperty, calling GetDependentProperties()
seems to yield what I am after being the FK property name ie:
public static String GetFKPropertyName(this NavigationProperty property)
{
var depProp = property.GetDependentProperties().FirstOrDefault();
if (depProp == null)
return "";
return depProp.Name;
}
精彩评论