Skip to content

SQlite: Exception "ExecuteReader can only be called when the connection is open." #1156

@avestnik

Description

@avestnik

I keep getting ExecuteReader exception. I tried to isolate it and it looks like it is thrown on query with .Include when previous query returned empty result set. below is code to reproduce it, Exception is throw on i == 1 after i == 0 returned empty set. when I comment out //.Include(t => t.Questions) it works just fine

using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Metadata;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Console3
{
    public class Question
    {
        public int TemplateId { get; set; }
        public int QuestionId { get; set; }
        public Template Template { get; set; }
        public decimal Score { get; set; }
    }

    public class Template
    {
        public Template()
        {
            Questions = new ObservableCollection<Question>();
        }
        public int TemplateId { get; set; }
        public string Name { get; set; }

        public ICollection<Question> Questions { get; set; }
    }

    public class LocalContext : DbContext
    {
        public LocalContext(DbContextOptions options)
            : base(options)
        {
        }

        public DbSet<Question> Questions { get; set; }
        public DbSet<Template> Templates { get; set; }

        public static IModel GetModel(bool create)
        {
            ModelBuilder modelBuilder = new ModelBuilder();

            var ts = modelBuilder.Entity<Template>();
            ts.Key(t => t.TemplateId);

            var qs = modelBuilder.Entity<Question>();
            qs.Key(q => q.QuestionId);
            if (!create)
            {
                qs.ManyToOne(q => q.Template, t => t.Questions).ForeignKey(q => q.TemplateId);
            }

            return modelBuilder.Model;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            DbContextOptions options = new DbContextOptions();
            options.UseSqlite("Filename=c:\\temp\\Questions.db");
            options.UseModel(LocalContext.GetModel(true));

            using (LocalContext create = new LocalContext(options))
            {
                create.Database.EnsureDeleted();
                create.Database.EnsureCreated();

                var id = create.Templates.Max(t1 => t1.TemplateId);
                int qid = create.Questions.Max(q1 => q1.QuestionId) + 1;

                for (int i = 1; i < 100; i++)
                {
                    var t = new Template { TemplateId = ++id, Name = "Name" };
                    create.Add(t);

                    for (int j = 1; j <= 30; j++)
                    {
                        var q = new Question { QuestionId = ++qid, TemplateId = t.TemplateId, Score = i * 1000 + j };
                        create.Add(q);
                    }

                    create.SaveChanges();
                }
            }

            DbContextOptions options2 = new DbContextOptions();
            options2.UseSqlite("Filename=c:\\temp\\questions.db");
            options2.UseModel(LocalContext.GetModel(false));
            using (LocalContext context = new LocalContext(options2))
            {
                context.Database.EnsureCreated();

                for (int i = 0; i < 100; i++)
                {
                    var template = context.Templates.Include(t => t.Questions).SingleOrDefault(t => t.TemplateId == i);

                    if (template == null) continue;

                    template.Name = DateTime.Now.ToString();

                    foreach (var q in template.Questions)
                    {
                        q.Score += 1.5m;
                    }
                    context.SaveChanges();
                }

            }
        }
    }
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions