2013-04-30 7 views
0

Я получаю следующую ошибку в одной из наших сред. Это происходит, когда IIS перезапускается, но мы не сузили специфику, чтобы воспроизвести его.Получение ошибки при создании объекта запроса в SubSonic

A DataTable named 'PeoplePassword' already belongs to this DataSet. 
at System.Data.DataTableCollection.RegisterName(String name, String tbNamespace) 
at System.Data.DataTableCollection.BaseAdd(DataTable table) 
at System.Data.DataTableCollection.Add(DataTable table) 
at SubSonic.SqlDataProvider.GetTableSchema(String tableName, TableType tableType) 
at SubSonic.DataService.GetSchema(String tableName, String providerName, TableType tableType) 
at SubSonic.DataService.GetTableSchema(String tableName, String providerName) 
at SubSonic.Query..ctor(String tableName) 
at Wad.Elbert.Data.Enrollment.FetchByUserId(Int32 userId) 

Основываясь на StackTrace, я считаю, что ошибка происходит на второй строке метода при создании объекта запроса. Пожалуйста, дайте мне знать, если у кого-то еще есть эта проблема. Спасибо!

Код для функции:

 public static List<Enrollment> FetchByUserId(int userId) 
    { 
     List<Enrollment> enrollments = new List<Enrollment>(); 
     SubSonic.Query query = new SubSonic.Query("Enrollment"); 
     query.SelectList = "userid, prompt, response, validationRegex, validationMessage, responseType, enrollmentSource"; 
     query.QueryType = SubSonic.QueryType.Select; 
     query.AddWhere("userId", userId); 
     DataSet dataset = query.ExecuteDataSet(); 
     if (dataset != null && 
      dataset.Tables.Count > 0) 
     { 
      foreach (DataRow dr in dataset.Tables[0].Rows) 
      { 
       enrollments.Add(new Enrollment((int)dr["userId"], dr["prompt"].ToString(), dr["response"].ToString(), dr["validationRegex"] != null ? dr["validationRegex"].ToString() : string.Empty, dr["validationMessage"] != null ? dr["validationMessage"].ToString() : string.Empty, (int)dr["responseType"], (int)dr["enrollmentSource"])); 
      } 
     } 
     return enrollments; 
    } 
+0

Не ответ, но используете ли вы последнюю версию версии 2.x от github? –

ответ

0

Это вопрос нарезание резьбы.

Subsonic загружает свою схему при первом вызове SubSonic.DataService.GetTableSchema(...), но это не проблема в потоковом режиме.

Позвольте мне продемонстрировать это небольшой пример

private static Dictionary<string, DriveInfo> drives = new Dictionary<string, DriveInfo>; 

private static DriveInfo GetDrive(string name) 
{ 
    if (drives.Count == 0) 
    { 
     Thread.Sleep(10000); // fake delay 
     foreach(var drive in DriveInfo.GetDrives) 
      drives.Add(drive.Name, drive); 
    } 
    if (drives.ContainsKey(name)) 
     return drives[name]; 
    return null; 
} 

это хорошо объясняет, что происходит, на первом вызове этого метода словарь пуст
Если это так, то метод поджать все диски.

Для каждого вызова возвращается требуемый диск (или null).

Но что произойдет, если вы запускаете метод два раза сразу после старта? Затем оба исполнения пытаются загрузить диски в словаре. Первый, кто добавит диск, выиграет второй, выкинет ArgumentException (элемент уже существует).

После предварительной предварительной загрузки все работает нормально.

Короче говоря, у вас есть два варианта.

  1. Изменить дозвуковой источник, чтобы сделать SubSonic.DataService.GetTableSchema(...) нить безопасной. http://msdn.microsoft.com/de-de/library/c5kehkcz(v=vs.80).aspx

  2. «Подогрев» дозвуковой перед принятием запросов. Техника для достижения этого зависит от дизайна вашего приложения. Для ASP.NET у вас есть Application_Start метод, который выполняется только один раз в течение всего жизненного цикла приложения http://msdn.microsoft.com/en-us/library/ms178473(v=vs.100).aspx

Таким образом, вы можете в основном положить

var count = new SubSonic.Query("Enrollment").GetRecordCount(); 

в методе, чтобы заставить дозвуковой инициализировать таблицу сама схема.

 Смежные вопросы

  • Нет связанных вопросов^_^