Согласно различным источникам, почти все пространство CSS полностью интернализировано и недоступно для разработчика. Я видел рекомендации о том, что мне следует перейти прямо к отображению xml, но я действительно не хотел этого делать ... Так что в конечном итоге я пришел к этому решению, которое, кажется, хорошо работает для получения всех отображений из ObjectContext.
Обратите внимание ... это дорого ... поэтому, если кто-то найдет это полезным и выберет такой подход, он должен обязательно его кешировать.
internal class Resource
{
public string Name {get; set; }
public Type Type { get; set; }
public IEnumerable<ResourceParameter> Parameters { get; private set; }
}
internal class ResourceParameter
{
public string Name { get; set; }
public Type Type { get; set; }
}
internal class EntityFrameworkExtensions
{
public static IEnumerable<Resource> GetResources(this ObjectContext objectContext, IEnumerable<Assembly> assemblies)
{
MetadataWorkspace metadataWorkspace = objectContext.MetadataWorkspace;
foreach (Assembly assembly in assemblies)
{
metadataWorkspace.LoadFromAssembly(assembly);
}
ReadOnlyCollection<EntityType> cSpaceEntityTypes = metadataWorkspace.GetItems<EntityType>(DataSpace.CSpace);
if (cSpaceEntityTypes != null)
{
foreach (Type type in cSpaceEntityTypes.Select(t => metadataWorkspace.GetClrType(t, assemblies)))
{
yield return new Resource { Type = type, Name = type.Name };
}
}
IEnumerable<EdmFunction> cSpaceFunctions = metadataWorkspace.GetItems<EntityContainer>(DataSpace.CSpace).SelectMany(c => c.FunctionImports));
if (cSpaceFunctions != null)
{
foreach (EdmFunction function in cSpaceFunctions)
{
Type returnType = metadataWorkspace.GetClrType(function.ReturnParameter.TypeUsage.EdmType, assemblies);
IEnumerable<ResourceParameter> parameters = function.Parameters.Select(p => new ResourceParameter(metadataWorkspace.GetClrType(p.TypeUsage.EdmType, assemblies), p.Name));
yield return new Resource { Type = returnType, Name = function.Name, Parameters = parameters };
}
}
}
public static string GetClrTypeName(this MetadataWorkspace metadataWorkspace, StructuralType cSpaceType)
{
if (cSpaceType != null)
{
StructuralType oSpaceType;
if (metadataWorkspace.TryGetObjectSpaceType(cSpaceType, out oSpaceType))
{
// interesting note: oSpaceType is of type ClrType - an internal EF type that contains a EdmType to CLR type mapping...
// so instead of getting the type name, we could go straight for the type
// by doing: oSpaceType.GetProperty("ClrType",BindingFlags.Instance|BindingFlags.NonPublic).GetValue(oSpaceType, null);
// but the classes are internal, so they might change and I don't want to touch them directly...
return oSpaceType.FullName;
}
}
return null;
}
public static Type GetClrType(this MetadataWorkspace metadataWorkspace, EdmType cSpaceEdmType, IEnumerable<Assembly> assemblies)
{
var collectionType = cSpaceEdmType as CollectionType;
if (collectionType != null)
{
Type elementType = metadataWorkspace.GetClrType(collectionType.TypeUsage.EdmType, assemblies);
return elementType;
}
var structuralType = cSpaceEdmType as StructuralType;
if (structuralType != null)
{
var name = metadataWorkspace.GetClrTypeName(structuralType);
foreach(var asm in assemblies)
{
var clrType = asm.GetType(name);
if (clrType != null)
{
return clrType;
}
}
}
var primitiveType = cSpaceEdmType as PrimitiveType;
if (primitiveType != null)
{
return primitiveType.ClrEquivalentType;
}
return null;
}
}