System.NullReferenceException после обновления до EF 4.1 - PullRequest
3 голосов
/ 20 марта 2011

У меня есть приложение MVC3, которое использовало EF CTP5. После обновления до EF 4.1 я получаю NullReferenceException брошенный отсюда:

   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.Initialize()
   at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
   at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
   at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
   at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
   at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)

Я получил 4,1 бит EF от NuGet.

База данных инициализируется с помощью пользовательского инициализатора

    public class RecreateDatabaseInitializer : IDatabaseInitializer<DatabaseContext>
    {
        public void InitializeDatabase(DatabaseContext context)
        {
            if (ConfigurationManager.ConnectionStrings["DatabaseContextSA"] == null)
            {
                EventLog.WriteEntry("RecreateDatabaseInitializer", "Connection string 'DatabaseContextSA' doesn't exist in config file.", EventLogEntryType.Warning);
                return;
            }

            using (var ctx = new DatabaseContext("DatabaseContextSA"))
            {
                if (ctx.Database.Exists())
                    DropDatabase(ctx);

                CreateDatabase(ctx);
                InitializeDatabaseObjects(ctx);
                ctx.SaveChanges();
            }

            PopulateDatabase(context);
            context.SaveChanges();
        }
    }

Исключение выдается методом PopulateDatabase().

Есть идеи?

UPDATE:

Кажется, что проблема связана с созданием второго DatabaseContext для ручного воссоздания базы данных. Это должно как-то мешать исходному контексту.

1 Ответ

1 голос
/ 20 марта 2011

Я использовал Декоратор Ладислава для закрытия открытых соединений , но мне пришлось немного его изменить.Это было необходимо (я полагаю), поскольку я использую аутентификацию sql и имею две строки подключения (одну с повышенными правами доступа и одну только для чтения / записи).

public class ForceDeleteInitializer : IDatabaseInitializer<DatabaseContext>
{
    private readonly IDatabaseInitializer<DatabaseContext> InnerInitializer;

    public ForceDeleteInitializer(IDatabaseInitializer<DatabaseContext> innerInitializer)
    {
        this.InnerInitializer = innerInitializer;
    }

    public void InitializeDatabase(DatabaseContext context)
    {
        using (var ctx = new DatabaseContext("DatabaseContextSA"))
        {
            Database.SetInitializer<DatabaseContext>(null);
            ctx.Database.ExecuteSqlCommand("ALTER DATABASE " + ctx.Database.Connection.Database + " SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
        }

        this.InnerInitializer.InitializeDatabase(context);

        Database.SetInitializer<DatabaseContext>(this);
    }
}
...