1

これが SO で重複していることはわかっていますが、特定のコードで contains 演算子を使用する方法がわかりません。

データベースには 5 つの予約があります。

ID、Booking、Pren、ReservationCode

1, VisitHere, 1, 1000A

2、VisitHere、1、1000A

3、VisitHere、1、1000A

4、VisitThere、2、2000A

5、VisitThere、2、2000A

    public int SpecialDelete(DataContext db, IEnumerable<BookingType> bookings) {

        var rescodes = (from b in bookings
                        select b).Distinct().ToArray();
        // Code Breaks here
        IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => bookings.Any(p => p.Pren == b.Pren && p.ReservationCode == b.ReservationCode));

        int deleted = bookingsToDelete.Count();
        db.GetTable<BookingType>().DeleteAllOnSubmit(bookingsToDelete);
        db.SubmitChanges();

        return deleted;
    }

最初のレコード (1, VisitHere, 1, 1000A) をこのメソッドに渡すと、ID 1、2、および 3 が取得されますが、4 と 5 は取得されません。

これを行うには、Pren と ReservationCode を一致させます。

.Any および .All 演算子が上記の例外をスローしているため、これを行うにはどうすればよいですか?

注:引数は常にメソッドに渡される複数の予約であるため、メソッドは予約のリストを受け入れる必要があります。例として単一の予約を使用しました。

編集:基本的に、次のような一連の SQL ステートメントを生成するには LINQ2SQL が必要です (たとえば、DB 内のすべてのレコードを削除したいとします):

DELETE
FROM Bookings b
WHERE b.ReservationCode = '1000A' AND b.Pren = 1

DELETE
FROM Bookings b
WHERE b.ReservationCode = '2000A' AND b.Pren = 2
4

3 に答える 3

1

サーバーに準一時テーブルがある場合はどうなりますか。そこにリストの値を入れることができます。

これは、ORM の実際の問題です。ローカル機能とリモート機能の間に多くのミスマッチがあります。

.Range を使用して、参加するリモート リストを生成しようとしましたが、どちらも機能しません。

基本的に、データ アイランドを何らかの方法で再配置する必要があります (つまり、pren と rs のリストはどこから来るのか? サーバーのどこかにあるのか?)、またはローカル コレクションの 1 つをサーバーのステージング エリアにアップロードする必要があります。

于 2013-07-19T16:54:51.617 に答える
1

取得しているエラーは、単純な配列を渡す .Contains メソッドを使用するように指示しようとしています。デフォルトでは、その配列をIn次の形式の句に変換します。

Where foo In ("b1", "B2", "B3")

ここで、In 句で多次元配列を実行できないことに注意してください (実行する必要があります)。サーバー側をローカル配列に参加させることはできないため、複合キーの関係がある限り選択肢は限られます。

行を削除するために行をフェッチする必要がない場合は、コンテキストの ExecuteCommand を使用して削除を発行する方がおそらく高速です。必ずクエリをパラメータ化してください ( http://www.thinqlinq.com/Post.aspx/Title/Does-LINQ-to-SQL-eliminate-the-possibility-of-SQL-Injectionを参照) 。

string deleteQuery = "DELETE FROM Bookings b WHERE b.ReservationCode = {0} AND b.Pren = {1}";
foreach (var bookingType in bookings)
{
    db.ExecuteCommand(deleteQuery, bookingType.ReservationCode, bookingType.Preen);
}
于 2013-07-19T21:12:05.953 に答える
0

エラー メッセージには、「contains 演算子を除く」と表示されます。Contains 演算子の使用を検討しましたか? 同じことを行う必要があります。

だからから

IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => bookings.Any(p => p.Pren == b.Pren && p.ReservationCode == b.ReservationCode));

IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => bookings.Contains(p => p.Pren == b.Pren && p.ReservationCode == b.ReservationCode));

リストには同じオブジェクトが含まれていないことに気付いたので、次のようなことをする必要があるかもしれません:

bookings.Select(booking => booking.PrimaryKeyOfAwesome).Contains(b => b.PrimaryKeyOfAwesome) etc etc. 


明確にするために編集

謙虚に編集 OK、セットアップ全体を実際に再作成した後、1 つだけでなく 2 つのパラメーターが原因でソリューションが機能しないことに気付きました。申し訳ありません。これは私が最終的に思いついたもので、うまくいきますが、本当にひどい解決策であり、使用すべきではありません. ここに含めるのは、締めくくりのためだけです ;)

        public static int SpecialDelete(DataContext db, IEnumerable<BookingType> bookings)
        {
            var compositeKeys = bookings.Select(b => b.Pren.ToString() + b.ReservationCode).Distinct();
            IEnumerable<BookingType> bookingsToDelete = db.GetTable<BookingType>().Where(b => compositeKeys.Contains(b.Pren.ToString() + b.ReservationCode));

            int deleted = bookingsToDelete.Count();
            db.GetTable<BookingType>().DeleteAllOnSubmit(bookingsToDelete);
            db.SubmitChanges();

            return deleted;
        }
于 2013-07-19T16:28:06.557 に答える