我尝试将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)'的最佳重载方法匹配有一些无效的参数
我该怎么办?
答案 0 :(得分: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();
答案 1 :(得分:2)
问题是您只是选择ID,然后与方法签名不匹配。我实际上将您的代码更改为:
var entity = aspnetdb.Trackpoints.Where(p => p.RouteFK == k).Single();
aspnetdb.Trackpoints.DeleteOnSubmit(entity);
(当你将select
子句更改为select p
时,使用查询表达式变得毫无意义 - 一旦你使用了方法调用语法,它就有意义了在同一声明中调用Single
或First
。根据abatishchev的回答,这也可以是aspnetdb.Trackpoints.Single(p => p.RouteFK == k)
。)
顺便说一下,假设您确实为给定的RouteFK提供了1个(并且只有1个)实体。
在单个查询中选择 all 要删除的实体可能实际上更好。例如:
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选择”问题。)
答案 2 :(得分: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();
}
}