JonPSmith / EfCore.GenericServices

A library to help you quickly code CRUD accesses for a web/mobile/desktop application using EF Core.
https://www.thereformedprogrammer.net/genericservices-a-library-to-provide-crud-front-end-services-from-a-ef-core-database/
MIT License
601 stars 94 forks source link

UpdateAndSaveAsync() returns Success but throwns Object is not registered as entity class #29

Closed S0PEX closed 5 years ago

S0PEX commented 5 years ago

Hey,

I am currently working on my side project and found this library after reading your book. Everything seems to work fine but for some reason, the UpdateAndSaveAsync() method returns success but then later EF Core throws The class Object is not registered as entity class in your DbContext PanelContext. Maybe you have a clue what's going on there because I had no luck debugging this issue. This is my Setup:

// Update Method input is a dto
await service.UpdateAndSaveAsync(input);
if(!service.IsValid)
    context.ReportError(service.GetAllErrors());
return service.Message;
// Dto
public class UpdateAppInDto : ILinkToEntity<App>
{
    public int AppId { get; set; }
    [Required(ErrorMessage = "Name is missing !")]
    public string Name { get; set; }
    public bool Active { get; set; } = false;
    public bool InviteNeeded { get; set; } = false;
    public bool AvailableForStaff { get; set; } = false;
    public bool AvailableForAdmins { get; set; } = true;
}
// App
public class App
{
    public int AppId { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public bool InviteNeeded { get; set; }
    public bool AvailableForStaff { get; set; }
    public bool AvailableForAdmins { get; set; }
}
// Startup block 
// GenericServices configuration
services.GenericServicesSimpleSetup<PanelContext>(Assembly.GetAssembly(typeof(UpdateAppInDto)));

After calling the update method as shown in the first snipped the value service.Message is Success but then when my methods returns the value of service.Message an exception if thrown The class Object is not registered as entity class in your DbContext PanelContext.. My guess would be that the AutoMapper fails but there a no other errors and the fact that the Message is set to Success is weird. Would really appreciate a hint.

Regards Artur

JonPSmith commented 5 years ago

Hi @S0PEX,

Sorry for the delay in replying - very busy at the moment.

The message The class Object is not registered as entity class in your DbContext PanelContext is produced by GenericServices and means that the input into the UpdateAndSaveAsync method was neither a DTO (i.e. a class with the ILinkToEntity<TEntity>) or a class that EF Core maps to the database.

From the code you give you do link to a class, so the possibilities are:

  1. You haven't got a DbSet<App> ... in your DbContext
  2. The input isn't a DTO or entity.

Its rather interesting that is says "The class Object ..." as it should give a name of the class, not Object. I would therefore look at point 2, i.e. your input isn't right.

I hope that helps.

S0PEX commented 5 years ago

I just resolved the error. After you mentioned that it should actually output the class name instead of object I double checked my implementation, because I wrapped your methods to forward the errors to my GraphQl API response, and indeed the input parameter type was object I then changed it to a template type and its working correctly.

Thanks for the hint.

I was also wondering if there is a nice way to check if the service was indeed successful or not. Because for example Updating app names to already existing one's results in a duplicate key exception but the service.isValid still returns true and the message is also set to Successful. Although I am already handling such cases in my wrappers it would be neat if the service would recognize such things.

JonPSmith commented 5 years ago

Hi @S0PEX,

Glad my comment helped. I will close this issue.

On your exception/service.isValid question they are two very different, and separate, devices to report errors:

Exceptions always take precedence over service.isValid, i.e. the state of service.isValid etc. has no meaning once an exception has been raised.