2012-09-24 107 views
0

我在寫一些代碼時遇到了一個奇怪的併發問題。你會問的第一件事是我爲什麼使用CF和使用DbModelBuilder ...以及我有可能有第N個數據庫都將是相同的,我必須保持數據的分離。我正在使用CF來阻止多個開發人員用他們的GUI爲我的模型炫耀一個大規模的模型生成問題。唉,這是我正在做的事情的基本代碼。DbModelBuilder併發問題

兩個控制檯書寫線不應該被擊中,但它們是。

您可以試試這個,讓我知道問題出在哪裏?

這是測試工具的控制檯應用程序:

class Program 
{ 
    static void Main(string[] args) 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      var workerObject = new Worker(); 
      var workerThread = new Thread(workerObject.DoWork); 
      workerThread.Start(); 
     } 
    } 
} 

public class Worker 
{ 
    public void DoWork() 
    { 
     var connections = new List<KeyValuePair<string, DynamicDb>> 
      { 
       new KeyValuePair<string, DynamicDb>("db1", new MyDynamicEntityLayer("db1").DynamicDb()), 
       new KeyValuePair<string, DynamicDb>("db2", new MyDynamicEntityLayer("db2").DynamicDb()) 
      }; 

     foreach (var db in connections) 
     { 
      if (db.Key == "db1" && db.Value.ConnectionString.Contains("db2")) 
       Console.WriteLine("THIS SHOULD NEVER HAPPEN!!! db1 : " + db.Value.ConnectionString); 
      if (db.Key == "db2" && db.Value.ConnectionString.Contains("db1")) 
       Console.WriteLine("THIS SHOULD NEVER HAPPEN!!! db2 : " + db.Value.ConnectionString); 
     } 
    } 
} 

下面是實體類:

public class MyDynamicEntityLayer 
{ 
    public static string ConnectionString { get; set; } 
    public MyDynamicEntityLayer(string db = null) 
    { 
     MakeAConnectionString(db); 
     Database.SetInitializer<DynamicDb>(null); 
    } 

    public void MakeAConnectionString(string db) 
    { 
     var sqlBuilder = new SqlConnectionStringBuilder(); 
     if (db == "db1") 
     { 
      sqlBuilder.DataSource = "MySqlServer"; 
      sqlBuilder.InitialCatalog = "db1"; 
      sqlBuilder.ConnectTimeout = 180; 
      sqlBuilder.IntegratedSecurity = true; 
     } 
     else 
     { 
      sqlBuilder.DataSource = "MySqlServer"; 
      sqlBuilder.InitialCatalog = "db2"; 
      sqlBuilder.ConnectTimeout = 180; 
      sqlBuilder.IntegratedSecurity = true; 
     } 

     ConnectionString = sqlBuilder.ToString(); 
    } 

    public DynamicDb DynamicDb() 
    { 
     var builder = new DbModelBuilder(DbModelBuilderVersion.Latest); 
     TableMappingToBuilder(builder); 
     var compiled = builder.Build(Database.DefaultConnectionFactory.CreateConnection(ConnectionString)).Compile(); 
     return new DynamicDb(compiled); 
    } 

    public void TableMappingToBuilder(DbModelBuilder builder) 
    { 
     builder.Configurations.Add(new EntityTypeConfiguration<ConcurrencyTest>()); 
     builder.Entity<ConcurrencyTest>().ToTable("ConcurrencyTest", "dbo"); 
    } 
} 

和我的DbContext CS文件:

public class DynamicDb : DbContext 
{ 
    public string ConnectionString { get; set; } 
    public DynamicDb(DbCompiledModel model) 
     : base(MyDynamicEntityLayer.ConnectionString, model) 
    { 
     ConnectionString = MyDynamicEntityLayer.ConnectionString; 
     ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 100; 
    } 
    public DbSet<ConcurrencyTest> ConcurrencyTests { get; set; } 
} 

public class ConcurrencyTest 
{ 
    public int ID { get; set; } 
    public string MyColumn { get; set; } 
} 
+0

什麼併發問題?如果你有問題,你應該描述它,否則你的問題將被關閉。 –

+0

這兩個控制檯的writeline絕不應該被擊中。 – YurikoEX

+0

謝謝你看Ladislav ...我已經看到你在這裏的工作。你可能很快就會發現這個問題! – YurikoEX

回答

1

你的問題是:

public class MyDynamicEntityLayer 
{ 
    public static string ConnectionString { get; set; } // STATIC PROPERTY 
    ... 

} 

所有工作線程共享存儲在此屬性中的單個值並爭奪其修改。

+0

我是一個盲人白癡......謝謝你,先生! – YurikoEX