我在编写linq查询时遇到问题,因为我是新手。我有两个表RosterSummaryData_Subject_Local
和RosterSummaryData_Subject_Local_Bands
。
Subject_Local
包含pkSummarySubjectLocalID
,Subject_Local_Bands
包含对该表的外键引用(fkSummarySubjectlocalID
)。 Subject_Local
包含永远不会使用的未使用或孤立的行。我想要做的是删除Subject_Local_Bands
中不存在的未使用/孤立的行。
例如,如果我们查看这些示例表:
RosterSummaryData_Subject_Local RosterSummaryData_Subject_Local_Bands
pkSummarySubjectLocalID pkSummarySubjectLocalBandID fkSummarySubjectLocalID Score
1 1 2 10
2 2 4 20
3 3 5 30
4
5
在这两个表中,您可以看到Subject_Local.pkSummarySubjectLocalIDs
中的Subject_Local_Bands
1和3 in永远不会被引用。我想将其从Subject_Local
中删除。
这是我目前使用的LINQ代码
var local = customerContext.RosterSummaryData_Subject_Local;
var localBands = customerContext.RosterSummaryData_Subject_Local_Bands;
IEnumerable<RosterSummaryData_Subject_Local> redundantSubjectLocalRows;
redundantSubjectLocalRows = from subjLocal in customerContext.RosterSummaryData_Subject_Local
join subjLocalBands in customerContext.RosterSummaryData_Subject_Local_Bands on
subjLocal.pkSummarySubjectLocalID equals subjLocalBands.fkSummarySubjectLocalID
where subjLocalBands.fkSummarySubjectLocalID != subjLocal.pkSummarySubjectLocalID
select subjLocal.pkSummarySubjectLocalID;
customerContext.RosterSummaryData_Subject_Local.RemoveRange(redundantSubjectLocalRows);
我想使用RemoveRange
所以我需要传递一个IEnumerable
我的上下文类RosterSummaryData_Subject_Local
,但我不知道如何使用linq查询创建它完成指定的条件。有什么帮助吗?
答案 0 :(得分:2)
可以说是不优雅的,但这应该是有效的:
HashSet<int> unorphanedIds new HashSet<int>(
RosterSummaryData_Subject_Local_Bands
.Select(b=>b.fkSummarySubjectLocalID));
var toRemove = customerContext.RosterSummaryData_Subject_Local
.Where(r=>!unorphanedIds.Contains(r.pkSummarySubjectLocalID));
customerContext.RosterSummaryData_Subject_Local.RemoveRange(toRemove);
customerContext.SaveChanges();
答案 1 :(得分:2)
var local = customerContext.RosterSummaryData_Subject_Local;
var localBands = customerContext.RosterSummaryData_Subject_Local_Bands;
你应该使用except。 A除外,B返回A中但不包含在B中的所有值。
我们选择除local.pkSummarySubjectLocalID
之外的所有localBands.fkSummarySubjectLocalID
,结果为pkSummarySubjectLocalID
但不在local
中的所有localBands
。
var orphanedIds = local.Select(x => x.pkSummarySubjectLocalID)
.Except(localBands.Select(x => x.fkSummarySubjectLocalID));
然后我们将此结果(orphanedIds
)加入local
并获取所有孤立的local
。
var orphaned = from l in local
join id in orphanedIds on l.pkSummarySubjectLocalID equals id
select l;
现在是时候删除所有孤儿local
。
local.RemoveRange(orphaned);
customerContext.SaveChanges();
答案 2 :(得分:1)
瑞恩
您可以使用LINQ查询中的以下语句创建RosterSummaryData_Subject_Local类。
public void TestMethod()
{
DataSet lDataSet = new DataSet();
var lOutput = (from lRosterSummaryBand in lDataSet.Tables[0].AsEnumerable()
select new RosterSummaryData_Subject_Local
{
//Assign the field value for each row to the model property specified.
//Make sure to use the correct data types specified from the data base.
pkSummarySubjectLocalID = lRosterSummaryBand.Field<System.Int64>("pkSummarySubjectLocalID") // Column name from DataTable / DataSet
}).ToList();//Make sure to set the output as an enumeration
}
数据存储在var集合中,但您可以使用()将它们转换为对象。
值得注意的是,当LINQ为这个var集合分配值时,它通过引用而不是值来实现。对var进行的任何更改都将改变DataTable / DataSet。
或者您也可以执行以下操作。这将保留连接两个表,将它们分配给模型,并只选择子表为空/无值的行。
var lRowsMarketForDeletion = (from lSubjectLocal in lDataSet.Tables[0].AsEnumerable()
join lSubjectLocalbands in lDataSet.Tables[1].AsEnumerable() on lSubjectLocal.Field<System.Int64>("pkSummarySubjectLocalID") equals lSubjectLocalbands.Field<System.Int64>("pkSummarySubjectLocalID") into lJoinedGroup
from lJoinedRow in lJoinedGroup.DefaultIfEmpty(new RosterSummaryData_Subject_Local { pkSummarySubjectLocalID = 0 })
where lJoinedRow.pkSummarySubjectLocalID == 0
select new RosterSummaryData_Subject_Local
{
pkSummarySubjectLocalID = lRosterSummaryBand.Field<System.Int64>("pkSummarySubjectLocalID")
}).ToList();
customerContext.RosterSummaryData_Subject_Local.RemoveRange(lRowsMarketForDeletion);
参考文献:
http://msdn.microsoft.com/en-us/library/bb311040.aspx加入表格。
linq to sql using select new inside class file选择每行的新对象。
http://www.dotnet-tricks.com/Tutorial/linq/UXPF181012-SQL-Joins-with-C左派如何工作。
如果您还有其他需要,请告诉我。