我有一个案例,我需要通过OData公开的实体是完全动态的(例如,用户可以配置他想要公开的字段)。来自存储库的查询结果存储在具有实际数据字典(FieldName / Value)的特殊泛型类中,因此CLR类型适用于所有类型。我对实体(实体名称,实体字段及其类型)有完整的了解。
因此我无法使用ODataModelBuilder方法(如Entity,EntitySet或HasKey(),EntityTypeConfiguration中的Property())在设计时构建EDM模型。
是否可以从头开始构建EDM模型? ODataModelBuilder使用EntityTypeConfiguration,但它依赖于实体的CLR类型。基本上我需要声明几种实体类型,所有实体类型都有一种CLR类型。
请告知。
答案 0 :(得分:9)
好的,所以我已经找到了解决这个问题的答案。
我编写了自己的OData模型构建器,它使用了Microsoft.Data.Edm.Library命名空间(EdmModel,EdmEntityType等)中的类型。
示例:
public IEdmModel GetEdmModel()
{
EdmModel model = new EdmModel();
EdmEntityContainer container = new EdmEntityContainer(Namespace, "DefaultContainer");
model.AddElement(container);
model.SetIsDefaultEntityContainer(container, isDefaultContainer: true);
EdmEntityType edmType = new EdmEntityType(Namespace, "Foo");
EdmStructuralProperty idProp = edmType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32), false);
edmType.AddKeys(idProp);
сontainer.AddEntitySet("MyEntitySet", edmType);
model.SetDataServiceVersion(new Version(3, 0, 0, 0));
model.SetMaxDataServiceVersion(new Version(3, 0, 0, 0));
return model;
}
答案 1 :(得分:0)
我这样解决了这个问题,
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "WebAPI";
builder.ContainerName = "DefaultContainer";
builder.EnableLowerCamelCase();
foreach (Type item in GetTypesInNamespace(System.Reflection.Assembly.Load("ProjectDLL"), "NamespaceOfModels"))
{
//My models have a key named "Id"
if (item.GetProperty("Id") == null)
continue;
EntityTypeConfiguration entityType = builder.AddEntityType(item);
entityType.HasKey(item.GetProperty("Id"));
builder.AddEntitySet(item.Name,entityType);
}
return builder.GetEdmModel();
}
在示例命名空间中获取类型
private static Type[] GetTypesInNamespace(System.Reflection.Assembly assembly, string nameSpace)
{
return assembly.GetTypes()
.Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal))
.ToArray();
}