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);
}
}
}
Create an OData v4 Endpoint Using ASP.NET Web API. 1 Create the Visual Studio Project. In Visual Studio, from the File menu, select New > Project. 2 Install the OData packages. 3 Add a model class. 4 Enable Entity Framework. 5 Configure the OData endpoint. More items
Web API OData 5.3 Entity type: A structured type with a key. Complex type: A structured type without a key. Open type: A type with dynamic properties. Both entity types and complex types can be open.
OData supports creating / deleting the relation between entities. In OData V3 relationship is referred to as "link" and in OData V4 relationship is refer as "reference". The relationship (reference) has its own URL in form of "/Entity/NavigationProperty/$ref". To add the relationship, client needs to send either POST or PUT request to the address.
Controller class is needed to inherit from ODataController and base class of ODataController is ApiController. In the body of the controller, I have defined GET method that returns the employee list and individual employee by id. Using the $expand, we can get or load the related entity.
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; }
}
I came here from google and ran into this error, here is an example of what my class looked like
public class TestEntity
{
[Key]
public int EntityID { get; }//<-- missing set
public string Name { get; set; }
}
only after I added the set to my [key] property did it get resolved. Here is the end result
public class TestEntity
{
[Key]
public int EntityID { get; set; }//<--- added set
public string Name { get; set; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With