0

So i have an existing class, which looks like this:

Public Class Song

    <Key>
    Public Property GUID As Guid

    <ForeignKey("Creator")>
    Public Property GUID_Creator As Guid

    Public Property Creator As User

End Class

This works perfectly, i'm able to add new songs and all that.

Recently, i decided i need to map some things using the Fluent API, but i didn't want to remake my whole model using the API, all i needed was just disabling cascade delete. So i wandered off to onModelCreating, to add

modelBuilder.Entity(Of Song) _

    .HasRequired(Function(s) s.Creator) _
    .WithMany(Function(u) u.Songs) _
    .HasForeignKey(Function(s) s.GUID_Creator) _
    .WillCascadeOnDelete(False)

I have added just that, the method was empty before. When firing the app after this (i have auto migrations enabled) and using the context, suddenly i get an exception for EVERY SINGLE CLASS in my context, saying:

EntityType 'Song' has no key defined
EntityType 'User' has no key defined

etc. I Googled for people using both Fluent API and Data Annotations at the same time, and found some people that had it working. Adding HasKey in the Fluent API solves it, but i don't wanna remake every class in OnModelCreating.
So how do i go about it? Is it possible to mix Fluent API and Data Annotations?

Tored
  • 55
  • 9

2 Answers2

0

Have a try and remove the line .HasKey(Function(s) s.GUID) _ from your entity calls, because you already defined it via Data Annotations and you only want to set up the relation:

modelBuilder.Entity(Of Song) _
    .HasRequired(Function(s) s.Creator) _
    .WithMany(Function(u) u.Songs) _
    .HasForeignKey(Function(s) s.GUID_Creator) _
    .WillCascadeOnDelete(False)

It should work that way. Maybe this post will help you.

But I have to recommend that you should avoid mixing Data Annotations and FluentAPI, because of splitting entity-definitions into different files will be much more error-prone!

ChW
  • 3,168
  • 2
  • 21
  • 34
  • I have edited the question, the `HasKey()` isn't in my code when this happens. – Tored Oct 23 '17 at 13:10
  • Okay. Could you add your condext class and relation related entity classes to the question. Currently I cannot see why it should not work. – ChW Oct 23 '17 at 13:18
  • My context class doesn't have anything else in it - just standard DbSets and a config that only enables auto migrations. I'll add for now that clean+rebuild didn't fix this. Also, I would have to upload my entire model, which I prefer not to do - the exception mentions every single class having no key (it worked before, and it works if I clean the `onModelCreating` function) – Tored Oct 23 '17 at 13:23
  • I see. Have you tried to remove the cascade on delete conventions? `protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Conventions.Remove(); modelBuilder.Conventions.Remove(); }` That will remove the cascade delete on all tables in your context, don't know if it is acceptable. – ChW Oct 23 '17 at 13:34
  • No, unfortunately I need cascade delete in most of my database. Might be a good last resort solution though. – Tored Oct 23 '17 at 14:05
0

Okay, i found my mistake, and i feel really stupid :D

What i have in my project is two classes:

Public Class Song 'Class for use in my apps and services
Public Class EF_Song 'Class for use with Entity Framework

So the entire problem was me using the class Song instead of EF_Song. The exception thrown was about all "standard" classes, because it tried to load them into the model based on their relationship with the Song class (obviously, the classes not meant for use with Entity Framework didn't have keys defined).

Tored
  • 55
  • 9