New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception "EntityType has no key defined" when upgrading to 0.5 #413

Closed
danroot opened this Issue May 27, 2016 · 6 comments

Comments

Projects
None yet
2 participants
@danroot

danroot commented May 27, 2016

I have an application using Restier 0.4-rc2 with an EF 6.1.3 dbcontext. The dbcontext uses external configuration classes to define schema, like this:

 public class AppDbContext{
  ...
   protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new AttorneyConfiguration());
         ...
   }
 }


public partial class AttorneyConfiguration : System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Attorney>
   {
       public AttorneyConfiguration()
           : this("dbo")
       {
       }

    public AttorneyConfiguration(string schema)
    {
        ToTable(schema + ".Attorney");
        HasKey(x => x.AttorneyName);
        ....
  }
 }

These classes are generated using the EF Reverse POCO generator. https://visualstudiogallery.msdn.microsoft.com/ee4fcff9-0c4c-4179-afd9-7a2fb90f5838

This all works as expected in 0.4 and a working OData endpoint is generated on top of this EF context with routes for all DbSets including Attorney.

Upgrading to 0.5 and switching from DbApi to EntityFrameworkApi, I get the error "EntityType Attorney has no key defined" when calling MapRestierRoute, even though it does in fact have a key defined both in the DB and in the configuration class. I suspect the Edm generation process is ignoring the EF configuration classes in .5 even though it did not ignore them in .4. I suspect "Attorney" is mentioned here just because it is the first one MapRestierRoute hits.

Any workaround for this would be appreciated- I'd really like to test some of the other .5 features but this is blocking me. Is there a way to ensure the Edm model is built using the full DbModel generated by EF?

@chinadragon0515

This comment has been minimized.

Contributor

chinadragon0515 commented May 30, 2016

In 0.5, we change the way to build model, the model is built with Web Api OData conversion model build, it reads all information from CLR class, the way it find the keys by these conversions,

  1. Any property defined with Key attribute in CLR class.
  2. If no property defined with key attribute, then it will find key by conversion, it will be property with name ID or EntityTypeID (like AttorneyID), case is ignore when finding the attribute.

You can refer to document http://odata.github.io/WebApi/#02-04-convention-model-builder, "Entity key convention" and "Key attribute" part for more detail on how key been found.

So for your case, there are two ways to fix the issue,

  1. Add key attribute to the AttorneyName property of your class.
  2. Or change the name of attorneyName to ID or attorneyID.

Either way will make model build work, let me know if this does not work for you.

Also let us know any other issues when you are migrating to 0.5 version, we want every consumers can smoothly migrate to 0.5 version. We always check issues here and questions in stackoverflow in time.

@chinadragon0515 chinadragon0515 self-assigned this May 30, 2016

@chinadragon0515

This comment has been minimized.

Contributor

chinadragon0515 commented Jun 6, 2016

No response within one week, close the issue, if you still have the issue, re-open the issue.

@danroot

This comment has been minimized.

danroot commented Jun 6, 2016

I have to disagree with this approach some. I understand the need to have a model convention for non-EntityFramework based models. But when starting from an EF-code-first model, the "thing" that should dictate the OData model IMO, is the EF model based on EF convention or configuration. My expectation would be that an Api around an EF Data Context would honor the model EF already has instead of force me to use it's own separate convention.

In this case, neither of the suggested fixes will work well due to some code gen scenarios. (The name must be AttorneyName, and adding Key attribute in the code gen will be difficult). And just conceptually, I don't want to modify my model just to make OData work.

@chinadragon0515

This comment has been minimized.

Contributor

chinadragon0515 commented Jun 7, 2016

@danroot We see your point,

We move to WebApi OData model builder for these reasons,

  1. As you said, for other data source
  2. Avoid duplicate code and utilize existing Web Api OData model for features like NoMapped attribute, derived type model build and so on.

I reopen the issue and will think and work out how we can provide more smooth user experience like this case.

@chinadragon0515

This comment has been minimized.

Contributor

chinadragon0515 commented Jun 8, 2016

After discussion, with Web Api OData model builder, keys can be specified, and will get key property name from DB, passed to the model builder to make the migration more smooth.

@chinadragon0515

This comment has been minimized.

Contributor

chinadragon0515 commented Jun 28, 2016

Fix merged, will be part of next release, close the issue.

@chinadragon0515 chinadragon0515 removed the ready label Jun 28, 2016

@chinadragon0515 chinadragon0515 added this to the 0.6 milestone Jun 29, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment