C# 如何更有效地填充用户详细信息集合
我有一个模块类、一个用户、一个UserModule和一个UserModuleLevel类 _模块_对象是模块的静态可观察集合,在程序启动时创建,大约有10个模块。e、 g.用户管理、客户服务等 您可能猜到的用户是用户详细信息:ID、名称等,由db查询填充 对于UserModules,我不在数据库中保存模块信息,只保留模块级别,这只是模块安全级别。这在数据库中保存为:用户ID、模块ID、模块级别、模块级别访问 我想做的是以最快的方式填充一个可观察的用户集合。我有大约120000个用户,通常这些用户只能访问10个模块中的2到3个 下面是我到目前为止已经尝试过的,但是带星号的部分是瓶颈,因为它要通过每个用户的每个模块 希望得到一些建议来加速事情的发展C# 如何更有效地填充用户详细信息集合,c#,wpf,C#,Wpf,我有一个模块类、一个用户、一个UserModule和一个UserModuleLevel类 _模块_对象是模块的静态可观察集合,在程序启动时创建,大约有10个模块。e、 g.用户管理、客户服务等 您可能猜到的用户是用户详细信息:ID、名称等,由db查询填充 对于UserModules,我不在数据库中保存模块信息,只保留模块级别,这只是模块安全级别。这在数据库中保存为:用户ID、模块ID、模块级别、模块级别访问 我想做的是以最快的方式填充一个可观察的用户集合。我有大约120000个用户,通常这些用户
public class UserRepository
{
ObservableCollection<User> m_users = new ObservableCollection<User>();
public UserRepository(){}
public void LoadUsers()
{
var users = SelectUsers();
foreach (var u in users)
{
m_users.Add(u);
}
}
public IEnumerable<User> SelectUsers()
{
var userModulesLookup = GetUserModules();
var userModuleLevelsLookup = GetUserModuleLevels().ToLookup(x => Tuple.Create(x.User_ID, x.Module_ID));
clsDAL.SQLDBAccess db = new clsDAL.SQLDBAccess("DB_USERS");
db.setCommandText("SELECT * FROM USERS");
using (var reader = db.ExecuteReader())
{
while (reader.Read())
{
var user = new User();
var userId = NullSafeGetter.GetValueOrDefault<int>(reader, "USER_ID");
user.User_ID = userId;
user.Username = NullSafeGetter.GetValueOrDefault<string>(reader, "USERNAME");
user.Name = NullSafeGetter.GetValueOrDefault<string>(reader, "NAME");
user.Job_Title = NullSafeGetter.GetValueOrDefault<string>(reader, "JOB_TITLE");
user.Department = NullSafeGetter.GetValueOrDefault<string>(reader, "DEPARTMENT");
user.Company = NullSafeGetter.GetValueOrDefault<string>(reader, "COMPANY");
user.Phone_Office = NullSafeGetter.GetValueOrDefault<string>(reader, "PHONE_OFFICE");
user.Phone_Mobile = NullSafeGetter.GetValueOrDefault<string>(reader, "PHONE_MOBILE");
user.Email = NullSafeGetter.GetValueOrDefault<string>(reader, "EMAIL");
user.UserModules = new ObservableCollection<UserModule>(userModulesLookup);
//**************** BOTTLENECK **********************************
foreach (var mod in user.UserModules)
{
mod.UserModuleLevels = new ObservableCollection<UserModuleLevel>(userModuleLevelsLookup[Tuple.Create(userId, mod.Module.Module_ID)]);
}
//**************************************************************
yield return user;
}
}
}
private static IEnumerable<Users.UserModule> GetUserModules()
{
foreach (Module m in ModuleKey._module_objects)
{
//Set a reference in the UserModule to the original static module.
var user_module = new Users.UserModule(m);
yield return user_module;
}
}
private static IEnumerable<Users.UserModuleLevel> GetUserModuleLevels()
{
clsDAL.SQLDBAccess db_user_module_levels = new clsDAL.SQLDBAccess("DB_USERS");
db_user_module_levels.setCommandText(@"SELECT * FROM USER_MODULE_SECURITY");
using (var reader = db_user_module_levels.ExecuteReader())
{
while (reader.Read())
{
int u_id = NullSafeGetter.GetValueOrDefault<int>(reader, "USER_ID");
int m_id = NullSafeGetter.GetValueOrDefault<int>(reader, "MODULE_ID");
int ml_id = NullSafeGetter.GetValueOrDefault<int>(reader, "MODULE_LEVEL_ID");
int mla = NullSafeGetter.GetValueOrDefault<int>(reader, "MODULE_LEVEL_ACCESS");
yield return new Users.UserModuleLevel(u_id, m_id, ml_id, mla);
}
}
}
}
公共类用户存储库
{
ObservableCollection m_users=新的ObservableCollection();
公共用户存储库(){}
公共void LoadUsers()
{
var users=SelectUsers();
foreach(用户中的var u)
{
m_用户。添加(u);
}
}
公共IEnumerable SelectUsers()
{
var userModulesLookup=GetUserModules();
var userModuleLevelsLookup=GetUserModuleLevels().ToLookup(x=>Tuple.Create(x.User\u ID,x.Module\u ID));
clsDAL.SQLDBAccess db=新的clsDAL.SQLDBAccess(“db_用户”);
db.setCommandText(“从用户中选择*);
使用(var reader=db.ExecuteReader())
{
while(reader.Read())
{
var user=新用户();
var userId=NullSafeGetter.GetValueOrDefault(读卡器,“用户ID”);
user.user_ID=用户ID;
user.Username=NullSafeGetter.GetValueOrDefault(读卡器,“用户名”);
user.Name=NullSafeGetter.GetValueOrDefault(读卡器,“名称”);
user.Job_Title=NullSafeGetter.GetValueOrDefault(读取器,“Job_Title”);
user.Department=NullSafeGetter.GetValueOrDefault(读卡器,“Department”);
user.Company=NullSafeGetter.GetValueOrDefault(读卡器,“公司”);
user.Phone\u Office=NullSafeGetter.GetValueOrDefault(读卡器,“Phone\u Office”);
user.Phone\u Mobile=NullSafeGetter.GetValueOrDefault(读卡器,“Phone\u Mobile”);
user.Email=NullSafeGetter.GetValueOrDefault(读卡器,“电子邮件”);
user.UserModules=新的ObservableCollection(userModulesLookup);
//****************瓶颈**********************************
foreach(user.UserModules中的var mod)
{
mod.UserModuleLevels=新的ObservableCollection(userModuleLevelsLookup[Tuple.Create(userId,mod.Module.Module\u ID)];
}
//**************************************************************
用户收益率;
}
}
}
私有静态IEnumerable GetUserModules()
{
foreach(模块key.\u模块\u对象中的模块m)
{
//在UserModule中设置对原始静态模块的引用。
var user_module=新用户。UserModule(m);
收益返回用户单元模块;
}
}
私有静态IEnumerable GetUserModuleLevel()
{
clsDAL.SQLDBAccess db_user_module_levels=新的clsDAL.SQLDBAccess(“db_USERS”);
db_user_module_levels.setCommandText(@“从用户_module_安全性中选择*);
使用(var reader=db\u user\u module\u levels.ExecuteReader())
{
while(reader.Read())
{
int u_id=NullSafeGetter.GetValueOrDefault(读卡器,“用户id”);
int m_id=NullSafeGetter.GetValueOrDefault(读卡器,“模块id”);
int ml_id=NullSafeGetter.GetValueOrDefault(读卡器,“模块级别id”);
int mla=NullSafeGetter.GetValueOrDefault(读卡器,“模块级访问”);
返回新的Users.UserModuleLevel(u\u id,m\u id,ml\u id,mla);
}
}
}
}
最后,我将把用户放入显示模块安全性的数据网格中,绿色按钮显示有某种类型的访问此模块的权限,单击它将显示实际的安全设置。为了提高性能,您可以做以下几件事:
- 更改数据访问代码以在SQL中执行联接,从而将数据作为单个结果集获取 SQL在返回关系数据的结果集方面往往比C#在事后将数据粘在一起要快得多。这是因为它被优化来实现这一点,您应该充分利用这一点
public static SqlExpressionVisitor<T> PageByRequest<T>(this SqlExpressionVisitor<T> expr, PagedRequest request)
{
return expr.Limit((request.PageNumber - 1) * request.PageSize, request.PageSize);
}
该方法被转换为T-SQL,并根据
[Alias("Customers")]
public class Customer : IHasId<string>
{
[Alias("AccountCode")]
public string Id { get; set; }
public string CustomerName { get; set; }
// ... a load of other fields
}
SELECT <A big list of Fields> FROM
(SELECT ROW_NUMBER() OVER (ORDER BY AccountCode) As RowNum, * FROM "Customers")
AS RowConstrainedResult
WHERE RowNum > 40 AND RowNum <= 50