布尔值不能更改
Posted
技术标签:
【中文标题】布尔值不能更改【英文标题】:Bool value cannot be changed 【发布时间】:2016-07-11 17:58:22 【问题描述】:我打算在到期日期结束后自动停用用户。因此,在查看用户帐户详细信息时,超过到期日期的用户帐户应显示为非活动状态(使用 fa-toggle on/off - 显示帐户的活动/非活动状态 - 在代码中它是一个布尔值 true/false )。
现有:
-
点击获取帐户详细信息时,
将从显示的 DB 中提取详细信息,
提取后将显示在应用程序中
我做了什么?
-
点击获取帐户详细信息时,
将从显示的 DB 中提取详细信息,
在向最终用户显示之前,
我正在尝试通过比较当前日期和到期日期来更改客户的活动/非活动详细信息。
提取后将显示在应用程序中
现有代码:
public IEnumerable<CustomerDetails> GetCustomerDetails(string groupName)
IEnumerable<CustomerDetails> customers;
var query = "select up.username, up.firstname, up.lastname, up.lastactivitydate, up.expirydate, " +
"up.activationdate, up.licensedby, up.position, up.isactive as isActiveUser, " +
"wr.rolename, up.usergroup, ul.contracttype as contracttype, ul.numberoflicense as " +
"licensesallowed from userprofile up inner join userlicense ul on ul.id = up.firmid inner join " +
"webpages_UsersInRoles wur on wur.userid = up.userid inner join webpages_Roles wr on " +
"wr.roleid = wur.roleid where ul.firmname='" + firmname.Replace("'", "''") + "' order by up.lastname";
using (IDbConnection dbConnection = new SqlConnection(UserDBConnectionString))
dbConnection.Open();
using (var result = dbConnection.QueryMultiple(query, commandTimeout: 300))
var accounts = result.Read().ToList();
customers = from account in accounts
select new CustomerDetails
FirstName = account.firstname,
LastName = account.lastname,
UserName = account.username,
PreviousUserName = account.username,
Position = account.position,
SharedSpace = JsonConvert.DeserializeObject<string[]>(account.usergroup),
UserRole = account.rolename,
IsActiveUser = account.isActiveUser,
LastActivityDate = account.lastactivitydate != null
? account.lastactivitydate.ToString("yyyy/MM/dd")
: "",
ExpiryDate = TimeZoneInfo.ConvertTimeToUtc((DateTime)account.expirydate),
ActivationDate = TimeZoneInfo.ConvertTimeToUtc((DateTime)account.activationdate),
ContractType = account.contracttype.ToString().Trim(),
LicensesAllowed = account.licensesallowed
;
return customers;
我所做的是在返回客户详细信息之前,return customers;
。我已经包含以下一组代码来停用所有超过激活期的用户。但它没有按预期工作。
// code as above shown
var count = customers.Count();
for (var i = 0; i < count;i++)
DateTime dateLimit = Convert.ToDateTime(customers.ElementAt(i).ExpiryDate);
DateTime currentDate = DateTime.Now.Date;
int result = DateTime.Compare(dateLimit,currentDate);
if (result == -1)
if (customers.ElementAt(i).IsActiveUser == true)
var beforeChanged = customers.ElementAt(i).IsActiveUser; // before it is true
customers.ElementAt(i).IsActiveUser = false; // i hope i am setting the value as false
var afterChanged = customers.ElementAt(i).IsActiveUser; // but i am still seeing true only here
return customers
编辑-1:
正如我在评论中所说,我可以将此处的值从 true 更改为 false,反之亦然。
编辑-2:
// 客户类结构
public class CustomerDetails
public string FirstName get; set;
public string LastName get; set;
public bool IsActiveUser get; set;
// some other fields ... goes here
我不知道将值设置为假后它仍然是真的。
【问题讨论】:
你能告诉我们 CustomerDetails 类吗? 可能是因为delayed execution
?您的 customers
似乎属于 IEnumerable
类型。另一种可能性是,由于IsActiveUser
是property
- 它的setter
可能不允许您将值设置为false
出于某种内部原因...
尝试将return customers;
更改为return customers.ToArray();
,看看问题是否消失。
正如@Ian 所说,问题在于执行延迟,您实际上是在枚举查询两次,每次都会为您提供一个新的CustomerDetails
s 列表。因此,当 UI 显示列表时,它不会显示您对第一个列表所做的更改。
一般来说,不要在数据库中存储可以根据现有数据计算的数据。如果非活动用户被定义为过期日期已过的用户,为什么需要存储 IsActiveUser
?
【参考方案1】:
你是deferred execution的受害者。
在这里,您每次调用customers
时都会查询您的数据库三次。
var beforeChanged = customers.ElementAt(i).IsActiveUser;
customers.ElementAt(i).IsActiveUser = false;
var afterChanged = customers.ElementAt(i).IsActiveUser;
每次,您从数据库加载对象,这就是您看不到任何变化的原因。数据库没有改变。
您需要具体化您的查询,可能通过在构建您的选择时对客户调用 .ToArray()
或 ToList()
。
【讨论】:
【参考方案2】:问题:customers 是 IEnumerable/IQueryable,而不是固定列表。它是“如何交付对象的定义”,而不是实际或稳定对象的列表。 每个对“元素”的引用都会导致customers
查询其源(列表),并在您检索它们时创建全新的对象。每……一次……一次。
解决方案:确保 customers
是使用 ToArrray() 或 ToList() 等持久化函数创建的。
【讨论】:
感谢您向我解释这个问题。现在我明白了。以上是关于布尔值不能更改的主要内容,如果未能解决你的问题,请参考以下文章