微风错误:“undefined不是函数”

时间:2013-06-10 11:15:12

标签: breeze

我有一个由EF代码优先创建的数据库,其中有两个主要类:'类别'和:'产品'。

每个类别都有一个产品列表的导航属性(与该类别相关的产品)。

我创建了一个web api,返回'IQueryable' - 所有与特定类别相关的产品。

这是api控制器 - 通过url调用时效果很好:

[HttpGet]
public IQueryable<Product> ProductsFilteredByCategory(int categoryId)
{

    return _contextProvider.Context.Categories.Include("Products").First(c => c.CategoryId == categoryId).Products.AsQueryable();

}

然而,当我通过以下功能从微风拨打电话时:

var getProducts = function (productsObservable, parentCategoryId) {

    var query = EntityQuery.from("ProductsFilteredByCategory")
    .withParameters({ categoryId: parentCategoryId });

    return manager.executeQuery(query)
    .then(querySucceeded)
    .fail(queryFailed);

} 

我收到以下错误:'undefined不是函数'。

奇怪的是,当我更改服务器端的控制器以返回所有产品的简单'IQyeryable'列表时 - 没有错误......但这不是我需要的 - 我只需要那些相关的产品具有特定类别......

感谢您的帮助!

Elior

2 个答案:

答案 0 :(得分:1)

你不必在你的控制器方法中使用这个参数,你可以删除参数并在你的breeze实体查询中用.where()声明它这样做的好处是你的控制器没有如此具体。

此外,您不需要使用.include(),因为breeze允许您使用.expand()扩展导航属性

这可以充分利用微风可以帮助您在项目中提供的帮助。

将ProductsFilteredByCategory(int categoryId)更改为

Public IQueryable<Product> Products()
{
    return _contextProvider.Context.Products();
}

你的微风查询

var query = EntityQuery.from('Products')
       .where('categoryId', '==', categoryId)
       .expand('Category');

如果您不想这样做,那么我认为您需要重做控制器方法。您应该返回产品实体,但是您要查询类别。

答案 1 :(得分:0)

非常感谢你们的支持,我很感激。

Kadumel,我无法使用您的解决方案,因为每个“产品”都可以属于多个“类别”,因此“产品”和“类别”没有参考形式。但是,我确实按照你的建议更改了控制器方法,现在情况正常。

这是代表所有内容的代码,希望它也可以帮助处于类似情况的其他人。我很乐意听到并提出改进代码的建议。

public class Category
{
    [Key]
    public int CategoryId { get; set; }
    [Required]
    public string Name { get; set; }
    public Int16? Order { get; set; }

    [ForeignKey("ParentCategoryId")]
    public Category ParentCategory { get; set; }
    public int? ParentCategoryId { get; set; }

    [ForeignKey("ParentCategory")]
    [InverseProperty("ParentCategory")]
    public List<Category> SubCategories { get; set; }

    [ForeignKey("ProductId")]
    public List<Product> Products { get; set; }
}
public class Product
{
    [Key]
    public int ProductId { get; set; }

    [Required]
    public string Name { get; set; }

    public string Desc { get; set; }

    public int Price { get; set; }

    //[ForeignKey("CategoryId")]
    //[InverseProperty("Products")]
    //public List<Category> Categories { get; set; }
}

(正如您所看到的,我注释了从“产品”到“类别”的向后链接列表,这些链接可能被用作从“产品”到“类别”的向后引用,因为Kdumel建议我使用这些链接,但是在我看来,如果没有它们,有这么多的参考文件太“重要”,你同意吗?)

这是控制器中的代码:

[HttpGet]
public IQueryable<Category> CategoryWithProducts(int categoryId)
{
    return _contextProvider.Context.Categories.Include("Products").Where(c => c.CategoryId == categoryId);
}

这是微风代码:

var getProducts = function (productsObservable, parentCategoryId) {
    var query = EntityQuery.from("CategoryWithProducts")
        .withParameters( {categoryId: parentCategoryId } )
        .select("Products");

    return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
        if (productsObservable) {
            productsObservable(data.results[0].products);
        }
        log('Retrieved [Products] from remote data source',
            data, true);
    }
};

正如您所看到的,结果是一个“类别”,我从中检索'querySuccedded()'函数中的'products'。

这有效,但我希望使用一种不起作用的不同方法:而不是传递'parentCategoryId'我尝试传递实际对象而不是ID作为'parentCategoryObj',然后我想到使用以下在不明确调用breeze控制器的情况下加载'products'导航属性的行:

parentCategoryObj.entityAspect.loadNavigationProperty("products")

但是,这导致没有加载“产品”,就像导航属性为null一样。奇怪的是,当我在这一行中将“products”改为“subCategories”时,只是为了检查导航属性是否是问题 - 'subCategories'数据已正确加载。我不明白为什么一个导航属性与另一个导航属性的行为不同(都是列表)。我更多地了解了这一点并注意到目前Breeze不支持“多对多”关系,我认为这就是原因,我是对的吗?...

再次感谢你们,知道好人愿意为你们提供帮助!

Elior