web-dev-qa-db-ja.com

行が見つからないか、単純なステートメントでLINQ C#エラーが変更されました

まず第一に、私はデータベースの開発バージョンでローカルに作業しているので、これがマルチユーザーの問題である可能性はありません。

あまり説明的ではないRow not found or changed db.SubmitChanges()を実行するとエラーがスローされます。 SubmitChanges()が発生する直前に実行を中断すると、SQL Server Management Studioにチェックインでき、行は存在します

これが関数全体のコードです。助けたい人のためにコンテキストに入れますが、問題の行は最後にあります(48行目)。

更新これは本当に奇妙なことです。エラーはmatchingTrans.Urlの更新によって発生します(コードの最後から2行目を参照)。この行をコメントアウトしても、matchingTrans.Titleがまだ更新されている場合でも、エラーはスローされません。

private static void MenuItemUpdate(int languageId, NavigationItem item)
{
    using (var db = DataContextFactory.Create<MyDataContext>())
    {
        // Select existing menu item from database.
        var dbItem =
            (from i in db.MenuItems
             where i.Id == item.Id
             select i).Single();
        // Obtain ID of link type.
        dbItem.FkLinkTypeId = GetLinkTypeByName(
            Enum.GetName(typeof (NavigationItemLinkType), item.LinkType)).Id;
        // Update the Link field with what is given.
        dbItem.Link = item.Link;
        db.SubmitChanges();

        // Item already exists and needs editing.
        // Get associated translations.
        var trans =
            from t in db.MenuItemTranslations
            where t.FkMenuItemId == item.Id
            select t;

        // If translation exists for given language, edit it.
        var matchingTrans =
            (from t in trans
             where t.FkLanguageId == languageId
             select t).SingleOrDefault();

        if (matchingTrans == null)
        {
            // No matching translation - add one.
            var newDbTrans = new MenuItemTranslation
            {
                FkMenuItemId = item.Id,
                FkLanguageId = languageId,
                Title = item.Title,
                Url = item.FriendlyUrl
            };
            db.MenuItemTranslations.InsertOnSubmit(newDbTrans);
            db.SubmitChanges();
        }
        else
        {
            // Matching translation - edit it.
            matchingTrans.Title = item.Title;
            matchingTrans.Url = item.FriendlyUrl;
            db.SubmitChanges();
            // WTF ERROR: Row not found or changed.
        }
    }
}
19
Greg

SQLプロファイラーの出力を見ると、これに対する答えを理解するのに役立ちました。生成されているSQLの不良部分があり、それはWHERE 0 = 1...明らかなエラーで終わりました。

別の開発者がnullを許可するようにフィールドが変更されただけであり、それに応じてLinq-to-SQLファイルが更新されていなかったことが判明しました。

つまり、理由もなくRow not found or changedエラーメッセージが生成されたように見える場合は、データベーススキーマが.dbmlファイルと完全に一致していることを確認してくださいそうでない場合は、次のフィールドでこのエラーメッセージが表示されます。スキーマが少し異なります。

47
Greg

SQLサーバーサーバーレベルの接続プロパティ「カウントなし」を確認してください

1。オブジェクトエクスプローラーでSQLサーバー接続を右クリック->プロパティ
2。 [接続]タブ/ページに移動します
3。デフォルトの接続オプション「カウントなし」を探します
4。このオプションがチェックされていないことを確認してください。

3
Shiju

ここで回答の優れたリストに追加することがわかったもう1つの可能性:

データベースでnull不可の列を使用する場合、それを本質的にnull許容のデータ型にマッピングすると(この例では、DB型はc#のバイト配列にマッピングされたLONG BLOB NOT NULLです)、更新する状況になる可能性があります。まったく同じバイト配列を持つデータベースでは、このエラーがスローされます。

例:ユーザーがデータベースに画像をアップロードできるWebサイトがあります。テーブルには、null許容ではないblob(SQLサーバーの画像など)があります。ユーザーは、すでに存在するのとまったく同じ画像でレコードを更新することを選択します。更新チェックは失敗します。最初に.SequenceEqual()チェックを実行し、次に着信バイト配列が既存のバイト配列と等しくない場合にのみコンテキストオブジェクトで.SubmitChanges()を呼び出すことで、これを修正しました。

2
Jeremy Harning

データベーススキーマとdbmlが完全に一致している場合でも、この問題が発生しました。問題は、エンティティを変更し、単一のSubmitChangesステートメントにエンティティを挿入しようとしていたことでした。一度にすべてではなく、各操作でSubmitChangesを実行することで修正しました。

これはすべてトランザクションスコープ内にあったため、何か関係があるかもしれませんが、よくわかりません。

1
William Casarin