Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ删除记录时出错_C#_.net_Linq_Linq To Sql_Exception Handling - Fatal编程技术网

C# 使用LINQ删除记录时出错

C# 使用LINQ删除记录时出错,c#,.net,linq,linq-to-sql,exception-handling,C#,.net,Linq,Linq To Sql,Exception Handling,我尝试将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();

我尝试将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

而您的
选择p.TrackPointId
将返回
Int


使用以下命令:

var eigen = (from p in aspnetdb.Trackpoints
            where p.RouteFK == k
            select p).First();
或者更短的是:

var eigen = aspnetdb.Trackpoints.First(p => p.RouteFK == k);
因为它返回
Trackpoint

而您的
选择p.TrackPointId
将返回
Int



问题是您只是选择了ID,而ID与方法签名不匹配。实际上,我会将您的代码更改为:

var entity = aspnetdb.Trackpoints.Where(p => p.RouteFK == k).Single();
aspnetdb.Trackpoints.DeleteOnSubmit(entity);
(当您将
select
子句更改为just
select p
时,使用查询表达式就变得毫无意义了——一旦您使用了方法调用语法,在同一语句中调用
Single
First
是有意义的。根据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选择”问题。)

问题在于您只是选择了ID,而ID与方法签名不匹配。我实际上会将您的代码更改为:

var entity = aspnetdb.Trackpoints.Where(p => p.RouteFK == k).Single();
aspnetdb.Trackpoints.DeleteOnSubmit(entity);
(当您将
select
子句更改为just
select p
时,使用查询表达式就变得毫无意义了——一旦您使用了方法调用语法,在同一语句中调用
Single
First
是有意义的。根据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选择”问题。)

方法需要域对象。您的代码将传递一个
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();
            }

        }

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

        }

LINQ to SQL或实体框架?LINQ to SQL。请简要说明LINQ to SQL和实体框架之间的区别好吗?LINQ to SQL是微软在实体框架之前推出的一种ORM,现在已被废弃和过时。LINQ to SQL或实体框架?LINQ to SQL。请简要说明LINQ to SQL和E之间的区别好吗实体框架?LINQ to SQL是Microsoft在实体框架之前的一种ORM,现在已被放弃和废弃。@Kabi:请注意调用
DeleteAllOnSubmit
以进一步简化代码的选项…@Kabi:请注意调用
DeleteAllOnSubmit
以进一步简化代码的选项。。。