Entity Framework Core Adding New Migration After Initial Creation - entity-framework-migrations

I have ASP.Net Core project and as ORM, it's based on Entity Framework Core version 3.1.8. It can be migrated and updated for first initial creation from CLor Package Manager Console, no worries. The problem is when I add a new table or a new property for existing entity, it's unable to add new migration. Exception details are below.
PM> dotnet ef migrations add "newone"
Build started...
Build succeeded.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Update.Internal.SharedTableEntryMap1.GetMainEntry(IUpdateEntry entry) at Microsoft.EntityFrameworkCore.Update.Internal.SharedTableEntryMap1.GetOrAddValue(IUpdateEntry entry)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffData(TableMapping source, TableMapping target, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Diff(TableMapping source, TableMapping target, DiffContext diffContext)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable1 sources, IEnumerable1 targets, DiffContext diffContext, Func4 diff, Func3 add, Func3 remove, Func4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator1.MoveNext() at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable1 operations, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IModel source, IModel target)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.
Also my DbContext & DbContextFactory code snippets are below
//My DbContextFactory CreateDbContext Method
public DataContext CreateDbContext(string[] args)
{
var env = GetEnvironment();
var connectionStr = SetDatabaseConnectionString(env);
var optionsBuilder = new DbContextOptionsBuilder<DataContext>();
optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable(connectionStr, EnvironmentVariableTarget.Machine));
optionsBuilder.EnableSensitiveDataLogging();
return new DataContext(optionsBuilder.Options, null);
}
//My DbContext Constructor
public DataContext(DbContextOptions<DataContext> options, IHttpContextAccessor httpContextAccessor) : base(options)
{
_logger = LogManager.GetCurrentClassLogger();
_logger.Info("Domain User : SYSTEM Details : DataContext initialized");
Database?.SetCommandTimeout(5000);//TODO : fetch from config
_httpContextAccessor = httpContextAccessor;
}

After lots of staff the problem is solved. It was, there is navigation property exists in entity but relation was not defined. After trying to add a new migration, null object reference exception was thrown but no details! I debugged all migration class, and at last realized the null object was the relation. I just advice if you face any kind of migration problem, comment all poco entities and check all entity navigations and relations step by step to find the problem.

Related

Cannot connect to my edmx with my data context

I've not used VS MVC for a while but I'm writing a project which requires connecting to a Sql database which I've installed as an edmx file SwitchDB.edmx in my DAL folder. In the past I've set up my data context file which I then use to reference the data in my controller, the model help me to order the data in the correct way.
This is how my data context file looks
namespace Switches.DAL
{
public class SwitchContext : DbContext
{
public SwitchContext()
: base("DefaultConnection")
{ }
public DbSet<Switch_List> SwitchList { get; set; }
}
}
I've set up the "DefaultConnection" in my Web.config under connectionStrings and my model Switch_List.cs has the file settings. When I declare the DB context in my controller as below
private SwitchContext db = new SwitchContext();
Then I would expect to reference the SwitchContext to get my data, like this
var switches= db.SwitchList .ToList();
However, when I run the project and reference db in debug I get the following error message 'the function evaluation requires all threads to run'. The DB context SwitchContext is clearly not getting access to the Switch.edmx so what am I forgetting?
I had a similar problem, but you should see the connection properties using an IDE button (to re-evaluate the expression).
However, when you get to the part of db.SwitchList.ToList() does it generate any exceptions?

How to update database programmatically from mvcArea

I'm using EF6 Code First Migrations for Multiple Models means working with a single database via multiple dbContext and Migrations, In MVC5!
Why?
Because i want to add new Entities to database from my Areas!..So each Area have their own dbContext and Migrations Files. i use Update-Database command in console package manager and my database will update without any problem.
As every body knows: You can update your database from each projects of your solution but if you set it as StartUpProject of solution.
and my challenge is about what i said in above Blockquote ! because in another step i want to update my database programmatically by this code:
//ActionResult of my Area:
public ActionResult Create()
{
var configuration = new Configuration();
var migrator = new DbMigrator(configuration);
migrator.Update(); //got Error in this line
return View();
}
i get
network-related or instance-specific error
in specified line and i know why!..because my Area Project is not set as StartUpProject of my solution and it shouldn't be.
So how can i handle this situation in your view?
I knew. i should give ConnectionString to my configuration instance, straightly like this:
public ActionResult Create()
{
var configuration = new Configuration();
configuration.TargetDatabase = new DbConnectionInfo(
"Server=.;Database=SegalFrameWork;Trusted_Connection=True;",
"System.Data.SqlClient");
configuration.ContextKey = "BlogDbContext";
var migrator = new DbMigrator(configuration);
migrator.Update();
return View();
}
now there is no need to read connection string from web.config so it doesn't need any startup project to find it.

On wrapping ObjectContext with DbContext

I am using EF 6.x with MVC 4 and VS2010.
I am testing an application where I have created database model from existing database, essentially I have added Edmx object to the application. I am at a very early stage of testing Generic Repository and Unity of Work. I have copied / pasted a block of code with some little adjustments from the ASP.NET website but I run into a problem that ObjectContext does not have functions such as Set(), Entry(), Find() etc. I tried to follow this answer on SO and wrap ObjectContext in DbContext:
public class GenericRepository<TEntity> where TEntity : class
{
private DbContext _dbcontext;
private StudentContext _context;
private DbSet<TEntity> _dbSet;
public GenericRepository(StudentContext context)
{
this._context = context;
this._dbcontext = new DbContext(_context, true); // type mismatch of input parameters
this._dbSet = _dbcontext.Set<TEntity>();
}
// ...
}
but compiler does not accept it due to wrong input parameters. _context is derived from ObjectContext. I was surprised because after reading this page I thought the constructor DbContext(ObjectContext objectContext, bool dbContextOwnsObjectContext) can create DbContext object if I provide StudentContext.
What am I missing?

L2S DataContext out of synch: row not found or changed

Psssst...!
Read on, by all means. But I can tell you here that the problem had nothing to do with the DataContext, but with Dependency Injection. I have left the question up, as it documents one possible issue with the "row not found or changed error" that has nothing to do with real world concurrency conflicts.
It seems the problems have been caused by badly written dependency injection. Or rather, I am beginning to believe, by default lifecycle management by the DI container I used.
The problem was that I used a DataContext as a constructor argument that was supplied by Ninject. It seems that the default behaviour was to cache this DataContext, leading to all manner of unexpected behaviour. I will ask a separate question about this.
Anyway, what follows is my original question, which as you will see, misses the real cause of the issue by a mile...
The Problem
I am getting a number of errors that imply that the DataContext, or rather, the way I am using the DataContext is getting out of synch.
The error occurs on db.SubmitChanges() where db is my DataContext instance. The error is:
Row not found or changed.
The problem only occurs intermitently, for example, adding a row then deleting it. If I stop the dev server and restart, the added row is there and I can delete it no problem.
Ie, it seems that the problem is related to the DataContext losing track of the rows that have been added.
IMPORTANT:
Before anyone votes to close this thread, on the basis of it being a duplicate, I have checked the sql server profiler and there is no "Where 0 = 1" in the SQL.
I have also recreated the dbml file, so am satisfied that the database schema is in synch with the schema represented by the dbml file.
Ie, no cases of mismatched nullable/not nullable columns, etc.
My Diagnosis (for what it is worth):
The problem seems (to me) related to how I am using the DataContext. I am new to MVC, Repositories and Services patterns, so suspect that I have wired things up wrong.
The Setup
Simple eLearning app in its early stages. Pupils need to be able to add and delete courses (Courses table) to their UserCourses.
To do this, I have a service that gets a specific DataContext instance Dependency Injected into its constructor.
Service Class Constructor:
public class SqlPupilBlockService : IPupilBlockService
{
DataContext db;
public SqlPupilBlockService(DataContext db)
{
this.db = db;
CoursesRepository = new SqlRepository<Course>(db);
UserCoursesRepository = new SqlRepository<UserCourse>(db);
}
// Etc, etc
}
The CoursesRepository and UserCoursesRepository are both private properties of the service class that are of type IRepository (just a simple generic repository interface).
SqlRepository Code:
public class SqlRepository<T> : IRepository<T> where T : class
{
DataContext db;
public SqlRepository(DataContext db)
{
this.db = db;
}
#region IRepository<T> Members
public IQueryable<T> Query
{
get { return db.GetTable<T>(); }
}
public List<T> FetchAll()
{
return Query.ToList();
}
public void Add(T entity)
{
db.GetTable<T>().InsertOnSubmit(entity);
}
public void Delete(T entity)
{
db.GetTable<T>().DeleteOnSubmit(entity);
}
public void Save()
{
db.SubmitChanges();
}
#endregion
}
The two methods for adding and deleting UserCourses are:
Service Methods for Adding and Deleting UserCourses:
public void AddUserCourse(int courseId)
{
UserCourse uc = new UserCourse();
uc.IdCourse = courseId;
uc.IdUser = UserId;
uc.DateCreated = DateTime.Now;
uc.DateAmended = DateTime.Now;
uc.Role = "Pupil";
uc.CourseNotes = string.Empty;
uc.ActiveStepIndex = 0;
UserCoursesRepository.Add(uc);
UserCoursesRepository.Save();
}
public void DeleteUserCourse(int courseId)
{
var uc = (UserCoursesRepository.Query.Where(x => x.IdUser == UserId && x.IdCourse == courseId)).Single();
UserCoursesRepository.Delete(uc);
UserCoursesRepository.Save();
}
Ajax
I am using Ajax via Ajax.BeginForm
I don't think that is relevant.
ASP.NET MVC 3
I am using mvc3, but don't think that is relevant: the errors are related to model code.
The problem only occurs intermitently,
for example, adding a row then
deleting it. If I stop the dev server
and restart, the added row is there
and I can delete it no problem.
Your code does not show what the link is between the Added Row and the Delete/Update. Your Add() doesn't return an object reference.
I'm thinking you are missing a Refresh (ie reload the object after Insert). Is your IdCourse also the PK in the Table?
Edit:
Further research has revealed that the problem is with the dependency injection.
The problem was related to how Dependency Injection manages the items it creates. Google for 'lifecycle management' in IoC or DI. Essentially, DI cached a DataContext constructor argument that I injected.
For a way to solve this using the Factory Pattern, see this thread:
Ninject caching an injected DataContext? Lifecycle Management?
The accepted answer solved it all.

Entity Framework NullReferenceException calling ToList?

I'm very new to WPF and the EF, and I'm trying to display some data from a table in a datagrid. I've got the entity model pulled from an existing database and simple operations seem to work (getting row counts, using 'first').
I'm running against Firebird 2.5.0 using the 2.0.5 DDEX provider and 2.5.2 ADO NETProvider.
When I try to get the data into the grid or simply into a list, I get a null reference exception.
Possibly I just don't understand how to use the entity framework, but the examples I see on the net make it look really easy.
public partial class Page1 : Page
{
Entities context;
public Page1()
{
context = new Entities();
InitializeComponent();
// This works to get a row into the grid
var arep = context.SALESREPs.First();
var alist = new List<SALESREP>();
alist.Add( arep );
gridUserList.ItemsSource = alist;
// These both fail with null ref exception
var allreps = context.SALESREPs.ToList();
gridUserList.ItemsSource = context.SALESREPs;
}
}
Here's the exception detail:
System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object.
Source=System.Data.Entity
StackTrace:
at System.Data.EntityKey.AddHashValue(Int32 hashCode, Object keyValue)
at System.Data.EntityKey.GetHashCode()
at System.Collections.Generic.GenericEqualityComparer`1.GetHashCode(T obj)
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at System.Data.Objects.ObjectStateManager.TryGetEntityEntry(EntityKey key, EntityEntry& entry)
at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at PSUserMaintenanceWebUI.Page1..ctor() in C:\Documents and Settings\d...\my documents\visual studio 2010\Projects\UserMaintenance\UserMaintenanceWebUI\Page1.xaml.cs:line 36
at System.Xaml.Schema.XamlTypeInvoker.DefaultCtorXamlActivator.InvokeDelegate(Action`1 action, Object argument)
at System.Xaml.Schema.XamlTypeInvoker.DefaultCtorXamlActivator.CallCtorDelegate(XamlTypeInvoker type)
at System.Xaml.Schema.XamlTypeInvoker.DefaultCtorXamlActivator.CreateInstance(XamlTypeInvoker type)
at System.Xaml.Schema.XamlTypeInvoker.CreateInstance(Object[] arguments)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstanceWithCtor(XamlType xamlType, Object[] args)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
InnerException:
My table has a multi-field primary key with some of the fields being nullable. The entity framework doesn't like nullable fields in the primary key. I removed those rows and it works fine. I'm already in the process of finding a different solution to the requirement that prompted us to allow nulls in some of the primary key fields.

Resources