Web APi OData V4 Issue "The entity '' does not have a key defined

Hanu picture Hanu · Jun 5, 2017 · Viewed 11k times · Source

When I run the following sample it is throwing the following exception...

Additional information: The entity 'TestEntity' does not have a key defined.

I have configured the key using code first entity context... modelBuilder.Entity<TestEntity>().HasKey(t => t.EntityID);

What is the issue? why is OData V4 not using the configured key?

namespace WebApplication2
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.MapODataServiceRoute("odata", "odata", model: GetEDMModel());

        }

        private static IEdmModel GetEDMModel()
        {
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<TestEntity>("TestEntities");             
            return builder.GetEdmModel();
        }
    }


    public class TestEntity
    {
        public int EntityID { get; set; }
        public string Name { get; set; }
    }

    public partial class TestContext1 : DbContext
    {

        public TestContext1() : base("DB")
        {
        }
        public DbSet<TestEntity> Entities { get; set; }        
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<TestEntity>().HasKey(t => t.EntityID);

        }
    }

}

Answer

woelliJ picture woelliJ · Jun 5, 2017

You defined the key for the database mapping of Entity Framework but not for the OData mapping.

Try this:

 private static IEdmModel GetEDMModel()
 {
       ODataModelBuilder builder = new ODataConventionModelBuilder();
       var entitySet = builder.EntitySet<TestEntity>("TestEntities");
       entitySet.EntityType.HasKey(entity => entity.EntityID)
       return builder.GetEdmModel();
 }

Or try adding a [Key] Attribute to your TestEntity to tell OData (and Entity Framework at the same time) what Property is the key.

Like so:

using System.ComponentModel.DataAnnotations;

public class TestEntity
{
    [Key]
    public int EntityID { get; set; }
    public string Name { get; set; }
}