C# OData V4的Web Api没有';我不能和哈斯基一起工作

C# OData V4的Web Api没有';我不能和哈斯基一起工作,c#,odata,asp.net-web-api2,odata-v4,C#,Odata,Asp.net Web Api2,Odata V4,我将web api 2.2用于odata v4,以下是模型: [Table("User")] public partial class User { public User() { UserRoles = new HashSet<UserRole>(); } [StringLength(50)] public string Id { get; set; } [Required] [StringLength(5

我将web api 2.2用于odata v4,以下是模型:

[Table("User")]
public partial class User
{
    public User()
    {
        UserRoles = new HashSet<UserRole>();
    }

    [StringLength(50)]
    public string Id { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    public virtual ICollection<UserRole> UserRoles { get; set; }
}

[Table("UserRole")]
public partial class UserRole
{
    [Key]
    [Column(Order = 0)]
    [StringLength(50)]
    public string UserId { get; set; }

    [Key]
    [Column(Order = 1)]
    [StringLength(50)]
    public string RoleName { get; set; }

    public virtual User User { get; set; }
}
[表(“用户”)]
公共部分类用户
{
公共用户()
{
UserRoles=newhashset();
}
[长度(50)]
公共字符串Id{get;set;}
[必需]
[长度(50)]
公共字符串名称{get;set;}
公共虚拟ICollection用户角色{get;set;}
}
[表(“用户角色”)]
公共部分类用户角色
{
[关键]
[第列(顺序=0)]
[长度(50)]
公共字符串用户标识{get;set;}
[关键]
[第列(顺序=1)]
[长度(50)]
公共字符串RoleName{get;set;}
公共虚拟用户用户{get;set;}
}
下面是WebApiConfig.cs代码:

        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<User>("Users");
        builder.EntitySet<UserRole>("UserRoles");            
        config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
        config.AddODataQueryFilter();
ODataConventionModelBuilder=new ODataConventionModelBuilder();
builder.EntitySet(“用户”);
builder.EntitySet(“用户角色”);
config.MapODataServiceRoute(“odata”,“odata”,builder.GetEdmModel());
config.AddODataQueryFilter();
到目前为止,一切都很顺利。 但是,如果我从UserRole定义中删除[Key]。并使用以下代码:

builder.EntitySet<UserRole>("UserRoles").EntityType.HasKey(r => new { r.UserId, r.RoleName });
builder.EntitySet(“UserRoles”).EntityType.HasKey(r=>new{r.UserId,r.RoleName});
当我查询用户时,我总是得到一个错误,告诉用户角色没有键定义

我已经上传了源项目文件@ 请检查webapiconfig.cs User.cs UserRole.cs和web.config(数据库连接字符串)。 当您访问/odata/Users?$expand=UserRoles时,会出现错误

只需更改即可

builder.EntitySet<UserRole>("UserRoles").EntityType.HasKey(r => new { r.UserId, r.RoleName });
builder.EntitySet(“UserRoles”).EntityType.HasKey(r=>new{r.UserId,r.RoleName});

EntityTypeConfiguration userRoleType=builder.EntitySet(“UserRoles”).EntityType;
HasKey(p=>p.UserId);
userRoleType.HasKey(p=>p.RoleName);
只需更改

builder.EntitySet<UserRole>("UserRoles").EntityType.HasKey(r => new { r.UserId, r.RoleName });
builder.EntitySet(“UserRoles”).EntityType.HasKey(r=>new{r.UserId,r.RoleName});

EntityTypeConfiguration userRoleType=builder.EntitySet(“UserRoles”).EntityType;
HasKey(p=>p.UserId);
userRoleType.HasKey(p=>p.RoleName);
只需更改

builder.EntitySet<UserRole>("UserRoles").EntityType.HasKey(r => new { r.UserId, r.RoleName });
builder.EntitySet(“UserRoles”).EntityType.HasKey(r=>new{r.UserId,r.RoleName});

EntityTypeConfiguration userRoleType=builder.EntitySet(“UserRoles”).EntityType;
HasKey(p=>p.UserId);
userRoleType.HasKey(p=>p.RoleName);
只需更改

builder.EntitySet<UserRole>("UserRoles").EntityType.HasKey(r => new { r.UserId, r.RoleName });
builder.EntitySet(“UserRoles”).EntityType.HasKey(r=>new{r.UserId,r.RoleName});

EntityTypeConfiguration userRoleType=builder.EntitySet(“UserRoles”).EntityType;
HasKey(p=>p.UserId);
userRoleType.HasKey(p=>p.RoleName);

我试过你的项目,我觉得odata元数据“/odata/$metadata”不错

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="WebApplication1.Models.OData" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="User">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.String" Nullable="false" />
        <Property Name="Name" Type="Edm.String" Nullable="false" />
        <NavigationProperty Name="UserRoles" Type="Collection(WebApplication1.Models.OData.UserRole)" />
      </EntityType>
      <EntityType Name="UserRole">
        <Key>
          <PropertyRef Name="UserId" />
          <PropertyRef Name="RoleName" />
        </Key>
        <Property Name="UserId" Type="Edm.String" Nullable="false" />
        <Property Name="RoleName" Type="Edm.String" Nullable="false" />
        <NavigationProperty Name="User" Type="WebApplication1.Models.OData.User" />
      </EntityType>
    </Schema>
    <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityContainer Name="Container">
        <EntitySet Name="Users" EntityType="WebApplication1.Models.OData.User">
          <NavigationPropertyBinding Path="UserRoles" Target="UserRoles" />
        </EntitySet>
        <EntitySet Name="UserRoles" EntityType="WebApplication1.Models.OData.UserRole">
          <NavigationPropertyBinding Path="User" Target="Users" />
        </EntitySet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

问题在于,UserRole没有在DB模型而不是OData EDM模型中定义键。

如果删除UserId和RoleName上的Key属性,DBModelBuilder将不知道这些键是什么

因此,您需要将以下代码添加到数据库中

modelBuilder.Entity<UserRole>()
                .HasKey(r => new { r.UserId, r.RoleName });
modelBuilder.Entity()
.HasKey(r=>new{r.UserId,r.RoleName});
此外,如果要支持在结果上应用$expand,则需要在操作上添加EnableQuery属性:

        [EnableQuery]
        public IQueryable<User> GetUsers()
        {
            var db = new Database();
            return db.Users;
        }
[启用查询]
公共IQueryable GetUsers()
{
var db=新数据库();
返回db.Users;
}

我试过你的项目,我觉得odata元数据“/odata/$metadata”不错

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="WebApplication1.Models.OData" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="User">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.String" Nullable="false" />
        <Property Name="Name" Type="Edm.String" Nullable="false" />
        <NavigationProperty Name="UserRoles" Type="Collection(WebApplication1.Models.OData.UserRole)" />
      </EntityType>
      <EntityType Name="UserRole">
        <Key>
          <PropertyRef Name="UserId" />
          <PropertyRef Name="RoleName" />
        </Key>
        <Property Name="UserId" Type="Edm.String" Nullable="false" />
        <Property Name="RoleName" Type="Edm.String" Nullable="false" />
        <NavigationProperty Name="User" Type="WebApplication1.Models.OData.User" />
      </EntityType>
    </Schema>
    <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityContainer Name="Container">
        <EntitySet Name="Users" EntityType="WebApplication1.Models.OData.User">
          <NavigationPropertyBinding Path="UserRoles" Target="UserRoles" />
        </EntitySet>
        <EntitySet Name="UserRoles" EntityType="WebApplication1.Models.OData.UserRole">
          <NavigationPropertyBinding Path="User" Target="Users" />
        </EntitySet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

问题在于,UserRole没有在DB模型而不是OData EDM模型中定义键。

如果删除UserId和RoleName上的Key属性,DBModelBuilder将不知道这些键是什么

因此,您需要将以下代码添加到数据库中

modelBuilder.Entity<UserRole>()
                .HasKey(r => new { r.UserId, r.RoleName });
modelBuilder.Entity()
.HasKey(r=>new{r.UserId,r.RoleName});
此外,如果要支持在结果上应用$expand,则需要在操作上添加EnableQuery属性:

        [EnableQuery]
        public IQueryable<User> GetUsers()
        {
            var db = new Database();
            return db.Users;
        }
[启用查询]
公共IQueryable GetUsers()
{
var db=新数据库();
返回db.Users;
}

我试过你的项目,我觉得odata元数据“/odata/$metadata”不错

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="WebApplication1.Models.OData" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="User">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.String" Nullable="false" />
        <Property Name="Name" Type="Edm.String" Nullable="false" />
        <NavigationProperty Name="UserRoles" Type="Collection(WebApplication1.Models.OData.UserRole)" />
      </EntityType>
      <EntityType Name="UserRole">
        <Key>
          <PropertyRef Name="UserId" />
          <PropertyRef Name="RoleName" />
        </Key>
        <Property Name="UserId" Type="Edm.String" Nullable="false" />
        <Property Name="RoleName" Type="Edm.String" Nullable="false" />
        <NavigationProperty Name="User" Type="WebApplication1.Models.OData.User" />
      </EntityType>
    </Schema>
    <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityContainer Name="Container">
        <EntitySet Name="Users" EntityType="WebApplication1.Models.OData.User">
          <NavigationPropertyBinding Path="UserRoles" Target="UserRoles" />
        </EntitySet>
        <EntitySet Name="UserRoles" EntityType="WebApplication1.Models.OData.UserRole">
          <NavigationPropertyBinding Path="User" Target="Users" />
        </EntitySet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

问题在于,UserRole没有在DB模型而不是OData EDM模型中定义键。

如果删除UserId和RoleName上的Key属性,DBModelBuilder将不知道这些键是什么

因此,您需要将以下代码添加到数据库中

modelBuilder.Entity<UserRole>()
                .HasKey(r => new { r.UserId, r.RoleName });
modelBuilder.Entity()
.HasKey(r=>new{r.UserId,r.RoleName});
此外,如果要支持在结果上应用$expand,则需要在操作上添加EnableQuery属性:

        [EnableQuery]
        public IQueryable<User> GetUsers()
        {
            var db = new Database();
            return db.Users;
        }
[启用查询]
公共IQueryable GetUsers()
{
var db=新数据