简体   繁体   English

使用LINQ删除记录时出错

[英]Error while deleting a record with LINQ

I try to change a SQL Delete command into LINQ. 我尝试将SQL Delete命令更改为LINQ。 this is my SQL Command: 这是我的SQL命令:

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

and this is the LINQ code that I've written: 这是我编写的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();
}

but in this line I have an error: 但在这一行中我有一个错误:

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

that said: 那说:

The best overloaded method match for 'System.Data.Linq.Table.DeleteOnSubmit(LINQ_Test.Trackpoint)' has some invalid arguments 'System.Data.Linq.Table.DeleteOnSubmit(LINQ_Test.Trackpoint)'的最佳重载方法匹配具有一些无效的参数

What should I do? 我该怎么办?

Use this: 用这个:

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

or what is shorter: 或更短:

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

because it returns Trackpoint 因为它返回Trackpoint

While your select p.TrackPointId returns Int . 当您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();

The problem is that you're just selecting the ID, which then doesn't match the method signature. 问题在于您只是选择ID,然后该ID与方法签名不匹配。 I'd actually change your code to: 我实际上会将您的代码更改为:

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

(By the time you've change the select clause to just select p it becomes pointless to use a query expression - and once you're using the method-call syntax, it makes sense to call Single or First in the same statement. As per abatishchev's answer, this could also be aspnetdb.Trackpoints.Single(p => p.RouteFK == k) .) (当您将select子句更改为仅select p时,使用查询表达式就变得毫无意义-并且一旦使用了方法调用语法,就可以在同一条语句中调用SingleFirst 。根据abatishchev的回答,这也可能是aspnetdb.Trackpoints.Single(p => p.RouteFK == k) 。)

This assumes you've definitely got 1 (and only 1) entity for the given RouteFK, by the way. 假设您确实为给定的RouteFK拥有1个(只有1个)实体。

It might actually be rather better to select all the entities you want to delete in a single query. 实际上,在单个查询中选择要删除的所有实体可能会更好。 For example: 例如:

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

Or if you've got your joins set up in your model correctly, you can probably get rid of the explicit join: 或者,如果您在模型中正确设置了联接,则可以摆脱显式联接:

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

In both cases, you can avoid doing nearly as many queries. 在这两种情况下,您都可以避免进行几乎相同数量的查询。 (You avoid an "n+1 selects" problem.) (避免出现“ n + 1个选择”问题。)

The DeleteOnSubmit method expects the domain object. DeleteOnSubmit方法需要域对象。 Your code passes an ID instead. 您的代码改为传递一个ID Also, you lack a condition to check whether the item actually exists. 另外,您没有条件检查项目是否实际存在。

Try to rewrite your routine to something like: 尝试将例程改写为:

        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