当我尝试在模型中展开对象的导航属性时出现错误。
eg. /odata/Products?$expand=ProductDetails
我收到以下错误:
No NavigationLink factory was found for the navigation property 'ProductDetails' from entity type 'ProductModels.Models.Product' on entity set 'Products'. Try calling HasNavigationPropertyLink on the EntitySetConfiguration.
参数名称:navigationProperty
我的模型看起来像这样:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Name")]
public PersonDetails PersonDetails { get; set; }
}
public class PersonDetails
{
[Key]
public string FullName { get; set; }
public int Age { get; set; }
}
这是一个零到一的关系,您可以看到我的模型有点奇怪,因为PersonDetails链接到Person by Person.Name = PersonDetails.FullName但实体框架6确实处理它并生成类似SQL的SQL以下内容:
SELECT
[Extent1].[Id] AS [Id],
N'f4243347-5b4c-4790-a07d-e8beb80bea72' AS [C1],
[Extent1].[Name] AS [Name],
N'PersonDetails' AS [C2],
N'f4243347-5b4c-4790-a07d-e8beb80bea72' AS [C3],
[Extent2].[FullName] AS [FullName],
[Extent2].[Age] AS [Age],
CASE WHEN ([Extent1].[Name] IS NULL) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C4]
FROM [Persons] AS [Extent1]
LEFT OUTER JOIN [PersonDetails] AS [Extent2] ON [Extent1].[Name] = [Extent2].[FullName]
在结果中,许多ProductDetails记录都为null,这没关系。
但似乎OData Formatter在Person.Name为null时遇到问题。我的ProductsContext中有以下设置:
public System.Data.Entity.DbSet<Product> Products { get; set;
这个ODataConventionModelBuilder:
builder.EntitySet<Vehicle>("Products");
我没有ProductDetails的控制器,因为我不想直接访问它,只能通过Products控制器。
如果我添加:
builder.EntitySet<Vehicle>("ProductDetails");
然后我得到了一个:
The EDM instance of type '[ProductModels.Models.ProductDetails Nullable=True]' is missing the property 'FullName'.
这是有道理的,因为FullName在该ProductDetails记录上可能为null。
我能看到的唯一前进方法是使用HasNavigationPropertyLink,而不是像上面那样以标准方式构建ProductDetails。
有人能就我该做什么给我任何建议吗?
答案 0 :(得分:1)
将实体条目添加到ODataConfig.cs
,如下所示。
builder.EntitySet<EntityName>(typeof(EntityName).Name);
并且整个代码将是这样的
public static class ODataConfig
{
public static void Register(HttpConfiguration config)
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<EntityName>(typeof(EntityName).Name);
var model = builder.GetEdmModel();
config.Routes.MapODataRoute("odata", "odata", model);
config.EnableQuerySupport();
}
}
答案 1 :(得分:-1)
试试这段代码:
var products=builder.EntitySet<Vehicle>("Products");
products.HasNavigationPropertiesLink(
product.NavigationProperties,
(entityContext, navigationProperty) =>
{
object id;
entityContext.EdmObject.TryGetPropertyValue("ID", out id);
return new Uri(entityContext.Url.Link(ODataTestConstants.DefaultRouteName,
new
{
odataPath = entityContext.Url.CreateODataLink(
new EntitySetPathSegment(entityContext.NavigationSource.Name),
new KeyValuePathSegment(id.ToString()),
new NavigationPathSegment(navigationProperty))
}));
}, true);
答案 2 :(得分:-1)
这对我有用:
foreach (var navProp in products.EntityType.NavigationProperties)
{
products.HasNavigationPropertyLink(
navprop,
(entityContext, navigationProperty) =>
{
object id;
entityContext.EdmObject.TryGetPropertyValue("ID", out id);
return new Uri(entityContext.Url.CreateODataLink(
new EntitySetPathSegment(navprop.Name),
new KeyValuePathSegment(id.ToString())
));
}, false);
}