簡體   English   中英

使用LINQ刪除記錄時出錯

[英]Error while deleting a record with LINQ

我嘗試將SQL Delete命令更改為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)'的最佳重載方法匹配具有一些無效的參數

我該怎么辦?

用這個:

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();

問題在於您只是選擇ID,然后該ID與方法簽名不匹配。 我實際上會將您的代碼更改為:

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

(當您將select子句更改為僅select p時,使用查詢表達式就變得毫無意義-並且一旦使用了方法調用語法,就可以在同一條語句中調用SingleFirst 。根據abatishchev的回答,這也可能是aspnetdb.Trackpoints.Single(p => p.RouteFK == k) 。)

假設您確實為給定的RouteFK擁有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個選擇”問題。)

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();
            }

        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM