1

SQLの削除コマンドをLINQに変更しようとしています。これは私のSQLコマンドです:

DELETE FROM [TrackPoints]
WHERE [RouteFK] IN (SELECT RouteId
                    FROM Routes
                    WHERE UserId = @UserId)

これは私が書いたLINQコードです:

int UID =1;
FirstDataContext aspnetdb = new FirstDataContext();
var res1 = from q1 in aspnetdb.Routes
           where q1.UserId == UID
           select q1.RouteId;
foreach (var k in res1)
{
    var eigen = from p in aspnetdb.Trackpoints
                where p.RouteFK == k
                select p.TrackPointId;

    aspnetdb.Trackpoints.DeleteOnSubmit(eigen.First());
    aspnetdb.SubmitChanges();
}

しかし、この行にはエラーがあります:

aspnetdb.Trackpoints.DeleteOnSubmit(eigen.First());

それは言った:

'System.Data.Linq.Table.DeleteOnSubmit(LINQ_Test.Trackpoint)'に最適なオーバーロードされたメソッドの一致には、いくつかの無効な引数があります

私は何をすべきか?

4

3 に答える 3

5

これを使って:

var eigen = (from p in aspnetdb.Trackpoints
            where p.RouteFK == k
            select p).First();

または短いもの:

var eigen = aspnetdb.Trackpoints.First(p => p.RouteFK == k);

戻るのでTrackpoint

あなたselect p.TrackPointIdが戻っている間Int


var r = from r in aspnetdb.Routes
        join p in aspnetdb.Trackpoints on p.RouteId equals r.RouteFK
        where r.UserId == UID
        select p;

foreach (var x in r)
{
    aspnetdb.Trackpoints.DeleteOnSubmit(x);
}
aspnetdb.SubmitChanges();
于 2012-07-02T10:13:03.217 に答える
2

問題は、ID を選択しているだけで、メソッド シグネチャと一致しないことです。私は実際にあなたのコードを次のように変更します:

var entity = aspnetdb.Trackpoints.Where(p => p.RouteFK == k).Single();
aspnetdb.Trackpoints.DeleteOnSubmit(entity);

(select節を justselect pに変更するまでに、クエリ式を使用するのは無意味になります。メソッド呼び出し構文を使用すると、同じステートメントでSingleorを呼び出すのが理にかなっていますFirst。 abatishchev の回答によると、これはの場合もありますaspnetdb.Trackpoints.Single(p => p.RouteFK == k)。)

ちなみに、これは、指定された RouteFK に対して確実に 1 つ (そして 1 つだけ) のエンティティがあることを前提としています。

実際には、1 回のクエリで削除するすべてのエンティティを選択する方がよい場合があります。例えば:

var entitiesToDelete = from q1 in aspnetdb.Routes
                       where q1.UserId == UID
                       join p in aspnetdb.TrackPoints 
                         on q1.RouteID equals p.RouteFK
                       select p;

aspnetdb.Trackpoints.DeleteAllOnSubmit(entitiesToDelete);
aspnetdb.SubmitChanges();

または、モデルで結合が正しく設定されている場合は、おそらく明示的な結合を取り除くことができます。

var entitiesToDelete = from q1 in aspnetdb.Routes
                       where q1.UserId == UID
                       select q1.Route; // Or Track, or whatever it is

aspnetdb.Trackpoints.DeleteAllOnSubmit(entitiesToDelete);
aspnetdb.SubmitChanges();

どちらの場合も、ほぼ同じ数のクエリを実行することを避けることができます。(「n+1 選択」の問題を回避します。)

于 2012-07-02T10:14:09.153 に答える
1

このDeleteOnSubmitメソッドは、ドメイン オブジェクトを想定しています。あなたのコードはID代わりにを渡します。また、アイテムが実際に存在するかどうかを確認する条件がありません。

ルーチンを次のように書き直してみてください。

        foreach (var k in res1)
        {
            var eigen = from p in aspnetdb.Trackpoints
                        where p.RouteFK == k
                        select p;

            var item = eigen.FirstOrDefault();

            if ( item != null )
            {
              aspnetdb.Trackpoints.DeleteOnSubmit(item);
              aspnetdb.SubmitChanges();
            }

        }
于 2012-07-02T10:14:46.647 に答える