Я создал для объектов пользователя объекты ObservableCollection объектов UserModule, называемые UserModules.Создание объектов из IDataReader
У меня приблизительно. 100000 записей пользователя, каждый пользователь может иметь до 10 записей модулей, и для этого требуется несколько минут.
Это может означать изменение из IDataReader, открытого для предложения. Может ли кто-нибудь предложить более эффективный способ сделать это?
public void LoadUsers()
{
clsDAL.SQLDBAccess db = new clsDAL.SQLDBAccess("USERS");
clsDAL.SQLDBAccess db_user_modules = new clsDAL.SQLDBAccess("USERS");
try
{
db.setCommandText(@"SELECT * FROM Users");
using (var reader = db.ExecuteReader())
{
while (reader.Read())
{
var user = new User();
MapUser(reader, user);
_users.Add(user);
db_user_modules.setCommandText(@"SELECT MODULE_ID, USER_MODULE_ACCESS FROM USER_MODULE_SECURITY Where USER_ID = " + user.User_ID);
using (var reader_user_modules = db_user_modules.ExecuteReader())
{
while (reader_user_modules.Read())
{
MapUserModule(reader_user_modules, user);
}
}
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
throw;
}
finally
{
db = null;
}
}
MapUser
public static void MapUser(IDataRecord record, User user)
{
try
{
user.User_ID = NullSafeGetter.GetValueOrDefault<int>(record, "USER_ID");
user.Username = NullSafeGetter.GetValueOrDefault<string>(record, "USERNAME");
user.Name = NullSafeGetter.GetValueOrDefault<string>(record, "NAME");
user.Job_Title = NullSafeGetter.GetValueOrDefault<string>(record, "JOB_TITLE");
user.Department = NullSafeGetter.GetValueOrDefault<string>(record, "DEPARTMENT");
user.Company = NullSafeGetter.GetValueOrDefault<string>(record, "COMPANY");
user.Phone_Office = NullSafeGetter.GetValueOrDefault<string>(record, "PHONE_OFFICE");
user.Phone_Mobile = NullSafeGetter.GetValueOrDefault<string>(record, "PHONE_MOBILE");
user.Email = NullSafeGetter.GetValueOrDefault<string>(record, "EMAIL");
user.Password = NullSafeGetter.GetValueOrDefault<string>(record, "PASSWORD");
user.Last_Login = NullSafeGetter.GetValueOrDefault<DateTime>(record, "LAST_LOGIN");
user.Status = NullSafeGetter.GetValueOrDefault<int>(record, "STATUS");
user.Session_Timeout = NullSafeGetter.GetValueOrDefault<int>(record, "SESSION_TIMEOUT");
}
catch (Exception ex)
{
MessageBox.Show("Mapping User error: " + ex.Message);
throw;
}
}
MapUserModule
private static void MapUserModule(IDataRecord record, User user)
{
try
{
int m_id = NullSafeGetter.GetValueOrDefault<int>(record, "MODULE_ID");
int uma = NullSafeGetter.GetValueOrDefault<int>(record, "USER_MODULE_ACCESS");
user.UserModules.Add(new Users.UserModule(user.User_ID, m_id, uma));
}
catch (Exception ex)
{
throw new Exception("Mapping UserModule error:\n" + ex.Message);
}
}
Поиск проблемы с n + 1. Большая часть вашей медлительности должна быть из-за того, что вы замкнуты в запросе 'UserModule'. Предполагая, что у вас 100000 пользователей, этот запрос выполняется 100000 раз. Предполагая, что в вашей базе данных будет латентность 1 мс (невероятно быстро), это займет 100000 мс или 100 с, что равно примерно 2 минутам. Короче говоря, 2 минуты (по крайней мере) в вашем коде составлены из задержек в сети. – Aron
Если я запустил его без добавления пользовательских модулей, это займет около секунды. – Hank
Мой совет, выберите все UserModules в одном запросе, поместите их все в 'ILookup'. Затем получите всех пользователей, а затем выполните user.UserModules = userModuleLookup [user.Id] .ToList() '. – Aron