当我更改属性的值时,Linq2Sql创建了一个额外的实例 - 为什么?

时间:2012-09-14 07:16:08

标签: linq-to-sql

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

基本上,表格如下所示:

User Properties Table

列:CreatedOn,ModifiedOn,CreatedBy和ModifiedBy不是DAL(dbml)的一部分,因为它们严格用于调试purpuses。触发器设置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的行从数据库读取旧值时(旧的))。

callstack看起来像这样(我在构造函数中放置了一个断点并在(2)之后捕获了screendumb:

Call stack just after (2)

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

Windows:Windows 7旗舰版64位 Visual Studio:Visual Studio 2010 Ultimate

1 个答案:

答案 0 :(得分:0)

您的Linq to SQL代码似乎有点不正统,所以我在下面提供以下备用代码。请注意使用DataContext成员变量,构造函数和带有空检查的FirstOrDefault而不是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;
     }
}