Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net dotnetcore中的动态EDM模型创建_.net_Asp.net Web Api_Asp.net Core_Odata - Fatal编程技术网

.net dotnetcore中的动态EDM模型创建

.net dotnetcore中的动态EDM模型创建,.net,asp.net-web-api,asp.net-core,odata,.net,Asp.net Web Api,Asp.net Core,Odata,我在上看到了动态Odata路线和模型生成的示例 我需要相同的点网核心,但由于Asp.net和Asp.net核心在类/路由等方面有所不同。我无法将此代码转换为点网核心 有人能提供一些指导吗 我的Startup.cs Configure方法具有以下特性- IEdmModel model = this.GetEdmModel(app.ApplicationServices); IList<IODataRoutingConvention> routingCo

我在上看到了动态Odata路线和模型生成的示例

我需要相同的点网核心,但由于Asp.net和Asp.net核心在类/路由等方面有所不同。我无法将此代码转换为点网核心

有人能提供一些指导吗

我的Startup.cs Configure方法具有以下特性-

        IEdmModel model = this.GetEdmModel(app.ApplicationServices);

        IList<IODataRoutingConvention> routingConventions = new List<IODataRoutingConvention>();
        routingConventions.Insert(0, new MatchAllRoutingConvention());
        app.UseMvc(routeBuilder => routeBuilder.MapODataServiceRoute("odata", "odata", model, new CustomPathHandler(), routingConventions));
ODataEndpointController.cs-

public class ODataEndpointController : ODataController
{
    [EnableQuery]
    [ODataRoute]
    public EdmEntityObjectCollection Get()
    {
        // Get entity set's EDM type: A collection type.            
        ODataPath path = Request.ODataFeature().Path;
        IEdmCollectionType collectionType = (IEdmCollectionType)path.EdmType;
        IEdmEntityTypeReference entityType = collectionType.ElementType.AsEntity();

        // Create an untyped collection with the EDM collection type.
        EdmEntityObjectCollection collection =
            new EdmEntityObjectCollection(new EdmCollectionTypeReference(collectionType));

        // Add untyped objects to collection.
        DataSourceProvider.Get(entityType, collection);

        return collection;
    }
MatchAllRoutingConvention.cs

public class MatchAllRoutingConvention : IODataRoutingConvention
{
    public IEnumerable<ControllerActionDescriptor> SelectAction(RouteContext routeContext)
    {
        ControllerActionDescriptor test = new ControllerActionDescriptor();
        test.ControllerName = "ODataEndpoint";
        return new List<ControllerActionDescriptor> { test }.AsEnumerable();

    }

}
公共类MatchAllRoutingConvention:IODataRoutingConvention
{
公共IEnumerable SelectAction(RouteContext RouteContext)
{
ControllerActionDescriptor测试=新的ControllerActionDescriptor();
test.ControllerName=“ODataEndpoint”;
返回新列表{test}.AsEnumerable();
}
}
这里有什么我做错的吗?当我尝试点击时,我得到一些源为空错误

编辑(1月15日):

如下所示修改MatchAllRoutingConvention会根据需要重定向路由,但任何$metadata请求(引发异常)也是如此。而$filter查询也不起作用。因此,任何提示/提示都会有所帮助-

public class MatchAllRoutingConvention : IODataRoutingConvention
{
    public IEnumerable<ControllerActionDescriptor> SelectAction(RouteContext routeContext)
    {
        ControllerActionDescriptor odataControllerDescriptor = new ControllerActionDescriptor
            {
                ControllerName = "ODataEndpoint",
                ActionName = "Get",
                Parameters = new List<ParameterDescriptor>(),
                FilterDescriptors = new List<FilterDescriptor>(),
                BoundProperties = new List<ParameterDescriptor>(),
                MethodInfo = typeof(ODataEndpointController).GetMethod("Get"),
                ControllerTypeInfo = typeof(ODataEndpointController).GetTypeInfo()
            };

            return new List<ControllerActionDescriptor> { odataControllerDescriptor };

    }

}
公共类MatchAllRoutingConvention:IODataRoutingConvention
{
公共IEnumerable SelectAction(RouteContext RouteContext)
{
ControllerActionDescriptor odataControllerDescriptor=新的ControllerActionDescriptor
{
ControllerName=“ODataEndpoint”,
ActionName=“Get”,
参数=新列表(),
FilterDescriptors=新列表(),
BoundProperties=新列表(),
MethodInfo=typeof(ODataEndpointController).GetMethod(“Get”),
ControllerTypeInfo=typeof(ODataEndpointController).GetTypeInfo()
};
返回新列表{odataControllerDescriptor};
}
}

将此作为答案发布,因为我还没有看到任何回复,希望这会对其他人有所帮助。我修改了MatchAllRoutingConvention类,如下所示-

public class MatchAllRoutingConvention : IODataRoutingConvention
{
    public IEnumerable<ControllerActionDescriptor> SelectAction(RouteContext routeContext)
    {
        if (routeContext.RouteData.Values["odataPath"] == null || 
            routeContext.RouteData.Values["odataPath"].ToString() == "$metadata")
            return new MetadataRoutingConvention().SelectAction(routeContext);

        IActionDescriptorCollectionProvider actionCollectionProvider =
            routeContext.HttpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();

        IEnumerable<ControllerActionDescriptor> actionDescriptors = actionCollectionProvider
            .ActionDescriptors.Items.OfType<ControllerActionDescriptor>()
            .Where(c => c.ControllerName == "ODataEndpoint");

        return actionDescriptors;
    }

}
公共类MatchAllRoutingConvention:IODataRoutingConvention
{
公共IEnumerable SelectAction(RouteContext RouteContext)
{
如果(routeContext.RouteData.Values[“odataPath”]==null | |
routeContext.RouteData.Values[“odataPath”].ToString()==“$metadata”)
返回新的MetadataRoutingConvention()。选择操作(routeContext);
IActionDescriptorCollectionProvider操作集合提供程序=
routeContext.HttpContext.RequestServices.GetRequiredService();
IEnumerable actionDescriptors=actionCollectionProvider
.ActionDescriptors.Items.OfType()
其中(c=>c.ControllerName==“ODataEndpoint”);
返回操作描述符;
}
}
这正确地服务于元数据请求以及简单的实体请求。然而,这并不响应$filter、$select等。据我所知,ODataQueryOptions类用于应用OData筛选等,但它们不适用于非CLR类。所以不确定是否有解决这个问题的方法

[编辑] 因此,我设法绕过了过滤问题。有一个库可以应用于IQueryable,而不是EdmEntityObjectCollection(显然不是那么容易)

我首先将数据加载到字典中,他们的网站上有这样一个例子。首先在该字典上应用OData查询选项字符串,然后将过滤结果加载到实体中,然后加载到EdmEntityObjectCollection中

    var list = new List<IEdmEntityObject>();
    var dataList = new List<Dictionary<string, object>>();

    // Load data in Dictionary
    foreach (var item in data)
    {
         var dataItem = new Dictionary<string, object>();

         // Load data

         dataList.Add(dataItem);
    }

    var filteredDataList = dataList.AsQueryable().LinqToQuerystring(oDataQuery);

    // Now add filtered/sorted etc data in EdmEntityObject
    foreach (var item in filteredDataList)
    {
         var entity = new EdmEntityObject(entityType);
         foreach (var key in item.Keys)
            entity.TrySetPropertyValue(key, item[key].ToString());
         list.Add(entity);
    }
var list=newlist();
var dataList=新列表();
//在字典中加载数据
foreach(数据中的var项)
{
var dataItem=新字典();
//加载数据
dataList.Add(dataItem);
}
var filteredDataList=dataList.AsQueryable().LinqToQuerystring(oDataQuery);
//现在在EdmEntityObject中添加过滤/排序的etc数据
foreach(filteredDataList中的变量项)
{
var实体=新的EdmEntityObject(entityType);
foreach(item.Keys中的变量键)
entity.TrySetPropertyValue(键,项[key].ToString());
列表。添加(实体);
}

ASP.NET Core中的OData支持仍处于预发布阶段。(尽管它现在显然已经进入了beta状态,考虑到signar仍然处于alpha状态,这是一件很重要的事情。)ASP.NET核心是一个完全不同的野兽,您正在查看的示例代码是针对ASP.NET MVC中稳定的OData的。不管是长是短,如果不是所有的事情都完全改变的话,相当多的事情可能已经改变了。不幸的是,由于它是预发布的,文档也非常缺乏。你在这里几乎是孤军奋战。如果您现在需要OData,我建议您暂时坚持使用Web Api。是的,您完全正确,我希望有人对OData和涉及的类有更好的了解,从而推动我朝着正确的方向前进。遗憾的是,Prelese、beta、undocumented这几个词在我的“上司”那里没有注册
    var list = new List<IEdmEntityObject>();
    var dataList = new List<Dictionary<string, object>>();

    // Load data in Dictionary
    foreach (var item in data)
    {
         var dataItem = new Dictionary<string, object>();

         // Load data

         dataList.Add(dataItem);
    }

    var filteredDataList = dataList.AsQueryable().LinqToQuerystring(oDataQuery);

    // Now add filtered/sorted etc data in EdmEntityObject
    foreach (var item in filteredDataList)
    {
         var entity = new EdmEntityObject(entityType);
         foreach (var key in item.Keys)
            entity.TrySetPropertyValue(key, item[key].ToString());
         list.Add(entity);
    }