C# .NET ODataController类返回与控制器类型在结构上无关的类型集合

C# .NET ODataController类返回与控制器类型在结构上无关的类型集合,c#,asp.net,odata,C#,Asp.net,Odata,我有一个类,MyClassController,它继承自ODataController。我已经能够使用“automagic”路由访问scaler集合类型的属性,例如使用/path/to/MyClass(100)/SomeProperty。现在,我需要返回一个类的集合,该类在结构上与MyClass无关(即,没有连接这两个类的引用),但在逻辑上,这两个类之间存在关系。我希望能够做一些类似于GETting/path/to/MyClass(100)/RelatedThings/的事情。我该怎么设置呢?我

我有一个类,
MyClassController
,它继承自
ODataController
。我已经能够使用“automagic”路由访问scaler集合类型的属性,例如使用
/path/to/MyClass(100)/SomeProperty
。现在,我需要返回一个类的集合,该类在结构上与
MyClass
无关(即,没有连接这两个类的引用),但在逻辑上,这两个类之间存在关系。我希望能够做一些类似于
GET
ting
/path/to/MyClass(100)/RelatedThings/
的事情。我该怎么设置呢?我正在使用
应用程序启动
中的
ODataConventionModelBuilder.EntitySet
设置
MyClass
及其相关类

我正在使用Microsoft.OData.Core 6.13.0(OData 4.0)


编辑:我在这个问题中遗漏了一些细节,我没有意识到这些细节与我在应用程序其他地方做出的一些设计决策有关,因此我接受了最能解决这个问题的答案,而没有考虑这些细节。最后,我在MyClass控制器中创建了一个绑定OData函数,该函数返回了相关内容。我发现如果没有包含名称空间或尾部斜杠,HTTP请求就会产生错误。也就是说,
/path/to/MyClass(100)/Default.RelatingThings/
有效。我正在寻找消除尾部斜杠和名称空间需要的方法。(编辑:设置OData路由时调用
config.EnableUnqualifiedNameCall(true)
;请参阅。)

由于数据在结构上不相关,因此无法扩展到相关实体。有一个oData扩展用于数据聚合、连接

使用扩展,它看起来像:

~/$crossjoin(Products,Sales)
                     ?$expand=Products($select=Name),Sales($select=Amount)
                     &$filter=Products/ID eq Sales/ProductID

您可以看到一个完整的示例

您的OData路由不必匹配存储架构中的关系;i、 例如,缺乏结构性关系是无关紧要的。只需将一个属性添加到
MyClass
,如下所示:

public ICollection<Thing> RelatedThings { get; set; }
public ICollection RelatedThings{get;set;}
然后定义属性的操作方法:

public IQueryable<Thing> GetRelatedThings([FromODataUri] int key)
{
    // Fill-in data access logic.
}
public IQueryable GetRelatedThings([FromODataUri]int键)
{
//填写数据访问逻辑。
}

您将无法请求
/path/to/MyClass(100)?$expand=RelatedThings
,但您可以根据需要请求
/path/to/MyClass(100)/RelatedThings

谢谢您的回复。我不熟悉OData交叉连接,但考虑到我想做的事情,这似乎太复杂了。我不想得到所有的产品和所有的销售。我只想得到一种特定产品的销售额。在您的示例中,我将是
GET
ting
/path/to/$crossjoin(产品、销售)?$filter=Products/ID-eq-Sales/ProductID-and-Products/ID=2358
。是否无法使用
/path/to/Product(2358)/
?我还可以为销售人员创建一个新的控制器,但我希望确保需要产品ID。顺便说一句,我喜欢你的句柄和化身。你可以在两个请求中完成,你可以向你的类发出一个请求,然后向你的子类发出另一个请求,在其他id匹配的地方,然后在javascript中加入你的结果,或者在你使用数据的地方,是的,短路是一部很棒的电影,我不知道如何将第一类的ID作为第二类的强制参数。我试着做了一个函数,最后退出了。(我不记得是怎么发现的,但它非常有用!)无论如何,如果我要用
IQueryable Get()
方法制作一个
RelatedThingsController
,有没有办法为父ID添加一个必需的参数?我确实考虑过在
MyClassController
中创建一个OData函数来返回
RelatedThing
集合,但我不知道如何摆脱
默认值。
名称空间,但是这也可以是一种选择。看看这个链接,你可能会创建一个动作过滤器,加入实体之后,我确实考虑过,但是我想保持域对象在相似的域对象之间工作的方式。如果我按照您建议的方式更改数据模型,那么它将是我们模型中唯一一个来自自动水合的普通旧CLR对象的引用与不存在的对象的引用的位置。(我们的一些域对象来自NHibernate,另一些来自JSON HTTP服务。)我也非常反对使用带有注释的属性,“永远不要使用这个属性;它就在这里,这样OData就不会抱怨了。”OData服务公开的实体和关系不必直接匹配存储架构中的对象和关系。分别对存储对象和OData实体建模,并使用类似AutoMapper的库在这两个模型之间进行转换。这种方法可以让您公开
MyClass
RelatedThings
之间的逻辑关系,而无需公开对象存储方式或位置的任何细节。不过,我也希望这样。这让我的ORM处理分页而不是过滤,而不是让ORM处理整个结果集。我也不想再添加另一种数据表示形式。域对象、用于业务逻辑操作的数据传输对象和视图模型就足够了,尤其是当我添加另一个表示的原因是为了解决真正的路由问题时。