0

UserProperties というテーブルがあります。ユーザーごとに少数のユーザー プロパティのセットがあります。それらをプログラムの_userPropertiesという Dictionary にロードします(キャッシュされるように)。

基本的に、テーブルは次のようになります。

ユーザー プロパティ テーブル

列: 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) に到達すると、コンストラクターが再度呼び出され、2 番目のインスタンスが作成され、困惑します。

例外はスローされず、余分なインスタンスがテーブルに保存されます (余分なインスタンスにはプロパティ値の変更が含まれており、次に古い値が小さい ID (古いもの) を持つ行を介してデータベースから読み取られるため、バグが発生します) )。

コールスタックは次のようになります (コンストラクターにブレークポイントを設定し、(2) の直後にスクリーンダムをキャプチャしました。

(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していますが、単純に範囲外にすることをお勧めします (これに関するドキュメントはインターネット上の他の場所にあります)。

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 に答える