布尔值不能更改

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 类型。另一种可能性是,由于IsActiveUserproperty - 它的setter 可能不允许您将值设置为false 出于某种内部原因... 尝试将return customers; 更改为return customers.ToArray();,看看问题是否消失。 正如@Ian 所说,问题在于执行延迟,您实际上是在枚举查询两次,每次都会为您提供一个新的CustomerDetailss 列表。因此,当 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() 等持久化函数创建的。

【讨论】:

感谢您向我解释这个问题。现在我明白了。

以上是关于布尔值不能更改的主要内容,如果未能解决你的问题,请参考以下文章

更改布尔值的默认值

更改布尔值时无法在 SwiftUI 中更改按钮文本

父组件更改道具(布尔值)时子组件不更新

更改用户对象的布尔值

布尔值到字符串的聚合更改值

访问和更改长布尔值数组的最快实现是啥?