0

我将 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; }
}

以下是 WebApiConfig.cs 代码:

        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<User>("Users");
        builder.EntitySet<UserRole>("UserRoles");            
        config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
        config.AddODataQueryFilter();

到现在为止,每件事都运作良好。但是,如果我从 UserRole 定义中删除 [Key]。并使用代码:

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

当我查询用户时,我总是得到告诉用户角色没有键定义的错误。

我已经上传了源 porject 文件@https ://cloud.seafile.com/f/bdff340ec3/ 请检查 webapiconfig.cs User.cs UserRole.cs 和 web.config(用于数据库连接字符串)。当你访问 /odata/Users?$expand=UserRoles 你会得到错误

4

3 回答 3

2

只是改变

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

EntityTypeConfiguration<UserRole> userRoleType=builder.EntitySet<UserRole>("UserRoles").EntityType;
userRoleType.HasKey(p=>p.UserId);
userRoleType.HasKey(p=>p.RoleName);
于 2014-08-09T01:22:59.037 回答
1

我也有同样的问题。这是我现在正在做的事情,还没有完成,所以我不知道是否还会有其他问题。

在我的模型中,我将 UserId 更改为 Id,因此 OData 约定将其用作键,然后在我的 dbcontext 映射文件中使用:

public class DbLdapMap : EntityTypeConfiguration<DbLdap>
{
    public DbLdapMap()
    {
        ToTable("LDAP");

        //Primary Key
        HasKey(t => t.Id);

        // Properties
        Property(t => t.Id).HasColumnName("UserId");

    }
}

我真的很想将所有数据库定义保留在 Fluent API 中。

于 2017-01-16T20:54:37.987 回答
0

我尝试了您的项目,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 不知道键是什么。

所以你需要在Database.OnModelCreating中添加以下代码,不带[Key]:

modelBuilder.Entity<UserRole>()
                .HasKey(r => new { r.UserId, r.RoleName });

更重要的是,如果要支持在结果上应用 $expand,则需要在操作上添加 EnableQuery 属性

        [EnableQuery]
        public IQueryable<User> GetUsers()
        {
            var db = new Database();
            return db.Users;
        }
于 2014-08-11T07:03:25.293 回答