簡體   English   中英

實體框架DbContext實例DataReader已打開

[英]Entity Framework DbContext Instance DataReader already open

我沒有太多有關Entity Framework的經驗,所以我將盡力提供盡可能多的信息,並盡量不要使它太長。

這是我的DbContext:

using MySql.Data.Entity;
using MySql.Data.MySqlClient;
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Migrations;

namespace src.Database.Models
{
    [DbConfigurationType(typeof(MySqlEFConfiguration))]
    public class DefaultDbContext : DbContext
    {
        public DefaultDbContext(string connectionString) : base(connectionString)
        {
            System.Data.Entity.Database.SetInitializer(new MigrateDatabaseToLatestVersion<DefaultDbContext, MigrationConfiguration>());
        }

        public DbSet<User> Users { get; set; }
        public DbSet<Character> Characters { get; set; }
        public DbSet<CharacterClothes> CharacterClothes { get; set; }
        public DbSet<CharacterVehicles> CharacterVehicles { get; set; }
        public DbSet<Dealership> Dealership { get; set; }
        public DbSet<DealershipVehicle> DealershipVehicles { get; set; }
    }

    public class ContextFactory : IDbContextFactory<DefaultDbContext>
    {
        private static string ConnectionString;

        public static void SetConnectionParameters(string serverAddress, string username, string password, string database, uint port = 3306)
        {
            var connectionStringBuilder = new MySqlConnectionStringBuilder()
            {
                Server = serverAddress,
                UserID = username,
                Password = password,
                Database = database,
                Port = port
            };

            ConnectionString = connectionStringBuilder.ToString();
        }

        private static DefaultDbContext _instance;

        public static DefaultDbContext Instance
        {
            get
            {
                if (_instance != null) return _instance;
                return _instance = new ContextFactory().Create();
            }
            private set { }
        }

        public DefaultDbContext Create()
        {
            if (string.IsNullOrEmpty(ConnectionString)) throw new InvalidOperationException("Please set the connection parameters before trying to instantiate a database connection.");

            return new DefaultDbContext(ConnectionString);
        }
    }

    internal sealed class MigrationConfiguration : DbMigrationsConfiguration<DefaultDbContext>
    {
        public MigrationConfiguration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
            SetSqlGenerator("MySql.Data.MySqlClient", new MySqlMigrationSqlGenerator());
        }
    }
}

因此,它正在為我訪問的所有連接使用一個實例,如下所示:

var user = ContextFactory.Instance.Users.FirstOrDefault(x => x.id == id);
var dealerships = ContextFactory.Instance.Dealership.ToList();

而且工作正常!

雖然, 偶爾我會收到此錯誤:

已經有一個與此連接相關聯的打開的DataReader,必須先關閉它。

我想這是因為它正在嘗試使用實例,而該實例已經在使用中。

我一直在尋找如何解決它的日子,但仍然無法使它起作用。 我讀過有關MultipleActiveResultSets的信息,但我正在使用MySQL,似乎不支持它。

你應該改變它

private static DefaultDbContext _instance;

[ThreadStatic]
private static DefaultDbContext _instance;

最好為每個線程/請求創建一個新的DBContext實例。 通過線程共享相同的DbContext是危險且令人反感的。 這將導致不同的線程嘗試使用已被使用的相同DBContext實例。

另外,這里有一篇很好的文章關於UnitOfWork,事務管理以及為每個線程/請求創建DbContext的好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM