Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity framework: Null Reference Exception thrown when adding migration in package manager console VS 2012

i have been using entity framework code first migration in my mvc project. But recently after modifying my model class and adding new ones, when i try to use add-migration in package manager console, i keep getting this error : 'Object reference not set to an instance of an object' i am using entity framework version 5 and when i try using version 6 but it wont see my DbContext,here is my stack trace, please every suggestion will be welcomed.

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EdmEntityType entityType, EdmModel model)
   at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntities(EdmModel model)
   at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
   at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
   at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
   at System.Data.Entity.Migrations.Extensions.DbContextExtensions.<>c__DisplayClass1.<GetModel>b__0(XmlWriter w)
   at System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(Action`1 writeXml)
   at System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(DbContext context)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator()
   at System.Data.Entity.Migrations.Design.ToolingFacade.GetPendingMigrationsRunner.RunCore()
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
Object reference not set to an instance of an object.
like image 952
Cizaphil Avatar asked Nov 12 '22 00:11

Cizaphil


1 Answers

There was a missing piece in your repro but I found someone else reporting the same/similar issue here so I will use their example. Here is the repro:

public class Person
{
    public int PersonID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<Meeting> Meeting { get; set; }
}

public class Meeting
{
    public int MeetingID { get; set; }

    [ForeignKey("Customer")]
    public int CustomerID { get; set; }

    public virtual Person Customer { get; set; }

    [ForeignKey("SalesAgent")]
    public int SalesAgentID { get; set; }

    public virtual Person SalesAgent { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Meeting> Meetings { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Meeting>().HasRequired(m => m.Customer).WithMany(p => p.Meeting);
        modelBuilder.Entity<Meeting>().HasRequired(m => m.SalesAgent).WithMany(p => p.Meeting);
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var ctx = new MyContext())
        {
            EdmxWriter.WriteEdmx(ctx, XmlWriter.Create(Console.Out, new XmlWriterSettings { Indent = true }));
        }
    }
}

There is a bug in EF5 that causes the NullReferenceException. This does not work in EF6 either due to a different bug but I believe none of this is actually relevant here. I think the intention here was to map one navigation property from the Person entity to two navigation properties from the Meeting entity and this is not supported by EF (similarly you would not be able to tell just by looking at the contents of the Person.Meeting collection whether the user is in a meeting as a customer or as a sales agent (or both?) - you would have to compare key values/references - EF just does not do it). To fix this the model needs to be changed as follows:

public class Person
{
    public int PersonID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<Meeting> MeetingsAsCustomer { get; set; }

    public virtual ICollection<Meeting> MeetingAsSalesAgent { get; set; }
}

public class Meeting
{
    public int MeetingID { get; set; }

    [ForeignKey("Customer")]
    public int CustomerID { get; set; }

    public virtual Person Customer { get; set; }

    [ForeignKey("SalesAgent")]
    public int SalesAgentID { get; set; }

    public virtual Person SalesAgent { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }
    public DbSet<Meeting> Meetings { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Meeting>().HasRequired(m => m.Customer).WithMany(p => p.MeetingsAsCustomer);
        modelBuilder.Entity<Meeting>().HasRequired(m => m.SalesAgent).WithMany(p => p.MeetingAsSalesAgent);

    }

Now we have two navigation properties on the Person property that are mapped to the corresponding navigation properties on the Meeting entity.

like image 62
Pawel Avatar answered Nov 14 '22 23:11

Pawel