0

我有一个名为 UserProperties 的表。每个用户都有一小组用户属性。我将它们加载到程序中,放入名为_userProperties的字典中(以便兑现)。

基本上该表如下所示:

用户属性表

列:CreatedOn、ModifiedOn、CreatedBy 和 ModifiedBy 不是 DAL (dbml) 的一部分,因为它们严格用于调试目的。触发器设置 ModifiedBy 和 ModifiedOn。

当用户想要保存他的设置(或者程序认为他们应该被保存)我调用这个代码:

 string userPropertyValueAsString = (String)Convert.ChangeType(userPropertyValue, typeof(String));
 if (_userProperties.ContainsKey(userPropertyKey))
 {
     if (_userProperties[userPropertyKey] != userPropertyValueAsString)
     {
        using (DataAccessDataContext dataContext = CreateContext(JsApplication.CommitDal))
        {
(1)         UserProperty changedUserProperty = dataContext.UserProperties.First(u => u.fk_Employee == employeeId && u.PropertyName == userPropertyKey);
(2)         changedUserProperty.PropertyValue = userPropertyValueAsString;
            _userProperties[userPropertyKey] = changedUserProperty.PropertyValue;
            if (!dataContext.SubmitChanges())
            {
                throw new SubmitChangesException(employeeId);
            }
        }
    }
}

当我到达(1)时,类 UserProperty 的构造函数被调用(正如预期的那样,因为在数据库的表中找到了 UserProperty)。但是当我到达(2)时,再次调用构造函数,它创建了第二个实例,这让我感到困惑。

不会抛出异常并且额外的实例被保存到表中(这会导致错误,因为额外的实例包含更改属性值,并且下次通过具有较小 id 的行(旧的)从数据库中读取旧值时)。

调用堆栈看起来像这样(我在构造函数中放置了一个断点,并在 (2) 之后立即捕获了 screendumb:

在 (2) 之后调用堆栈

谁能告诉我为什么WPF会这样做以及我如何让它停止?

Windows:Windows 7 Ultimate 64 位 Visual Studio:Visual Studio 2010 Ultimate

4

1 回答 1

0

您的 Linq to SQL 代码似乎有点不正统,所以我在下面提供了以下替代代码。请注意使用 DataContext 成员变量、构造函数,并FirstOrDefault使用 null 检查而不是First(). true如果成功,false则函数返回,否则返回。尽管 Linq DataContext 实现了Dispose,但最好让它超出范围(您可以在 Internet 上的其他地方找到相关文档)。

public class UserSettings
{
     DataAccessDataContext dc;
     bool result = false;
     string[] _userProperties;

     public Settings(JSApplication application, string[] userProperties)
     {
         dataContext = CreateContext(application.CommitDal));
         _userProperties = userProperties;
     }

     public bool SaveUserSettings(string key, string settings)
     { 
         var property = dc.UserProperties.FirstOrDefault(u => u.fk_Employee == employeeId && u.PropertyName == userPropertyKey);
         if (property != null)
         {
              property.Value = settings;
              _userProperties[key] = settings;
              result = dc.SubmitChanges();
         }
         return result;
     }
}
于 2012-09-14T08:27:30.140 回答