【问题标题】:How to add EntitySet when using Breeze EdmBuilder使用 Breeze EdmBuilder 时如何添加 EntitySet
【发布时间】:2014-04-06 10:38:51
【问题描述】:

最终编辑:我会将答案放在此处,供其他正在搜索的人使用。主要问题是由 db-first 生成的 EDM 将“.Models”附加到模型命名空间的末尾导致的命名空间不匹配。此命名空间与 odata 命名空间不匹配,因此路由失败。我刚刚从命名空间中删除了所有出现的“.Models”,现在它可以工作了。


一个新手尝试设置了 webApiOdata 的 Breeze。对不起,如果这个问题是微不足道的。

我有一个带有 webapi odata 控制器的 db 生成的 edmx 模型。在我了解新的 Breeze EdmBuilder 之前,我一直无法显示正确的元数据。

这解决了显示正确元数据的问题,但现在,我无法路由到任何表。如果我尝试 /odata/Customers 我会收到 406 错误。

之前,我使用 ODataConventionModelBuilder 来设置 EntitySet,效果很好。

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Detail>("Details");
    builder.EntitySet<Item>("Items");
    builder.EntitySet<Order>("Orders");
    builder.EntitySet<Customer>("Customers");

现在,由于我使用的是 EdmBuilder,如何设置 EntitySet 以便可以路由到正确的数据?

我希望这个问题有意义。

* 编辑:我添加了 GCSodContext 列表和客户控制器的 sn-p。

namespace GCSbz3.Models
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;

    public partial class GCSodContext : DbContext
    {
        public GCSodContext()
            : base("name=GCSodContext")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public virtual DbSet<Customer> Customers { get; set; }
        public virtual DbSet<Detail> Details { get; set; }
        public virtual DbSet<Item> Items { get; set; }
        public virtual DbSet<Order> Orders { get; set; }
    }
}

这是客户控制器

...
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Http.OData;
using System.Web.Http.OData.Routing;
using GCSbz3.Models;

namespace GCSbz3.Controllers
{
    public class CustomersController : ODataController
    {
        private GCSodContext db = new GCSodContext();

        // GET odata/Customers
        [Queryable]
        public IQueryable<Customer> GetCustomers()
        {
            return db.Customers;
        }
...

这是 Customer 类。

namespace GCSbz3.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Customer
    {
        public Customer()
        {
            this.Orders = new HashSet<Order>();
        }

        public int CustID { get; set; }
        public string FName { get; set; }
        public string LName { get; set; }
        public string Phone { get; set; }

        public virtual ICollection<Order> Orders { get; set; }
    }
}

【问题讨论】:

  • 当您尝试 /odata/Customers 时,您会收到什么错误消息?

标签: entity-framework breeze asp.net-web-api-odata


【解决方案1】:

检查您的 ODataController 名称,它需要与您的 edmx 中的 EntitySet 名称对齐。

如果集合名称是 CustomerSet,控制器需要是 CustomerSetController 并具有公共 GetCustomerSet 方法。

例如这行得通;

TestDbContext.cs

public partial class TestDbContext : DbContext
{
    public TestDbContext()
        : base("name=TestDbContext")
    {}

    public virtual DbSet<A1> A1Set { get; set; }
}

A1SetController.cs

public class A1SetController : ODataController
{
    private TestDbContext db = new TestDbContext();

    // GET odata/A1Set
    [Queryable]
    public IQueryable<A1> GetA1Set()
    {
        return db.A1Set;
    }
}

WebApiConfig.cs

中的路由设置
// OData routes
config.Routes.MapODataRoute(
    routeName: "odata",
    routePrefix: "odata",
    model: EdmBuilder.GetEdm<TestDbContext>(),
    batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));

最后,edmx 和实际模型(类)命名空间需要对齐。当您向 $metadata 发出请求时,您会看到为您的模型定义的命名空间。您可以在您的模型设计器中更改它,右键单击空白区域,单击Properties。在属性窗口中,您可以看到 Namespace 属性。就我而言;

<Schema Namespace="Web">
    <EntityType Name="Customer">

还有 Customer.cs

namespace Web
{
    using System;
    using System.Collections.Generic;

    public partial class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

【讨论】:

  • 我在尝试“/odata/Customers”时收到 406 错误。 '/odata' 和 '/odata/$metadata' 都可以工作,但不是到控制器的路由
  • 我的上下文和控制器看起来都像你的示例。我能想到的唯一可能导致问题的是我的上下文名称不以“上下文”这个词结尾让我尝试更改它,看看是否会有所不同。
  • 改名后仍然出现 406 错误。我已将 sn-ps 添加到我原来的问题中。为什么在使用 ODataConventionModelBuilder 构建模型时,需要在模型中添加 '.EntitySet' 进行路由,而新的 EdmBuilder 不需要?
  • @ChiRow 可能由于命名空间差异而发生 406。我已经更新了我的答案,请检查最后一部分。还要检查您的路线配置,您不再使用 ODataConventionModelBuilder 了,对吧?当您向 /odata/$metadata 发出请求时,您还会看到元数据吗?
  • @ChiRow 客户类在 GCSbz3 或 GCSbz3.Models 命名空间中?这个命名空间和 edmx 需要对齐。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多