.net 获取IQueryable集合之间的差异
我有一张三列的桌子。两列组成PK。该表存储有关目录中文件的信息 我有一个文件目录作为输入 目标是获得添加和删除文件的列表 我有以下代码:.net 获取IQueryable集合之间的差异,.net,sql,linq,entity-framework,.net,Sql,Linq,Entity Framework,我有一张三列的桌子。两列组成PK。该表存储有关目录中文件的信息 我有一个文件目录作为输入 目标是获得添加和删除文件的列表 我有以下代码: string uri = "ftp://ftp.myftpsite.com/files"; FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(uri); ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory; FtpWebRespon
string uri = "ftp://ftp.myftpsite.com/files";
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(uri);
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
using (myEntities context = new myEntities())
{
IQueryable<ITEM> storedItems = from item in context.ITEMs where item.YEAR == "2013" select item;
List<ITEM> currentItemList = new List<ITEM>();
string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line) && line.EndsWith(".htm"))
{
ITEM item = new ITEM();
item.YEAR = line.Substring(0,4);
item.NUM = line.Substring(7,5);
currentItemList.Add(item);
line = streamReader.ReadLine();
}
IQueryable<ITEM> currentItems = currentItemList.AsQueryable<ITEM>();
IQueryable<ITEM> newItems = from item in currentItems where !(from storedItem in storedItems select storedItem.YEAR + storedItem.NUM).Contains(item.YEAR + item.NUM) select item;
IQueryable<ITEMS> removedItems = from item in storedItems where !(from currentItem in currentItems select currentItem.YEAR + currentItem.NUM).Contains(item.YEAR + item.NUM) select item;
List<ITEM> newItemsList = newItems.ToList();
List<ITEM> removedItemsList = removedItems.ToList();
}
因此,基本上,我没有在LINQ中执行条件语句,而是在for循环中的if语句中执行。老实说,我认为这很难看,但它有两个好处
你试过先投影吗?如果你的数据量不是太大,它不会杀死你。否则,你需要更具创造性
IQueryable<ITEMS> removedItems = from item in storedItems.ToList() where !(from currentItem in currentItems select currentItem.YEAR + currentItem.NUM).Contains(item.YEAR + item.NUM) select item;
IQueryable removedItems=来自storedItems.ToList()中的项,其中!(从currentItems中的currentItem选择currentItem.YEAR+currentItem.NUM)。包含(item.YEAR+item.NUM)选择项;
你的问题很奇怪。另一种方法可能有效,但我没有审查。你已经在2013年完成了子集划分,所以这也是一样的
List<int> itemNumbers = currentItems.Where(x=>x.YEAR ==2013).Select(x=>x.NUM).ToList();
IQueryable<ITEMS> removedItems = from item in storedItems where !itemNumbers.Contains(item.NUM) select item;
List itemNumbers=currentItems.Where(x=>x.YEAR==2013)。选择(x=>x.NUM.ToList();
IQueryable removedItems=来自storedItems中的项目,其中!itemNumber.Contains(item.NUM)选择项;
尝试以下方法:
using (myEntities context = new myEntities())
{
List<ITEM> storedItems = (
from item in context.ITEMs
where item.YEAR == "2013"
select item ).ToList();
List<ITEM> currentItemList = new List<ITEM>();
string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line) && line.EndsWith(".htm"))
{
ITEM item = new ITEM();
item.YEAR = line.Substring(0,4);
item.NUM = line.Substring(7,5);
currentItemList.Add(item);
line = streamReader.ReadLine();
}
List<ITEM> newItemsList = (
from cItem in currentItems
join sItem in storedItems
on ( cItem.YEAR + cItem.NUM ) equals ( sItem.YEAR + sItem.NUM )
into g
from gItem in g.DefaultIfEmpty()
where gItem == null
select cItem ).ToList();
List<ITEM> removedItemsList = (
from sItem in storedItems
join cItem in currentItems
on ( sItem.YEAR + sItem.NUM ) equals ( cItem.YEAR + cItem.NUM )
into g
from gItem in g.DefaultIfEmpty()
where gItem == null
select sItem ).ToList();
}
使用(myEntities context=new myEntities())
{
列表存储数据项=(
来自context.ITEMs中的项
其中item.YEAR==“2013”
选择项);
List currentItemList=新列表();
string line=streamReader.ReadLine();
而(!string.IsNullOrEmpty(line)和&line.EndsWith(“.htm”))
{
项目=新项目();
项目年=行子串(0,4);
item.NUM=行子字符串(7,5);
currentItemList.Add(项目);
line=streamReader.ReadLine();
}
列表newItemsList=(
从当前项目中的cItem
在storedItems中加入sItem
on(cItem.YEAR+cItem.NUM)等于(sItem.YEAR+sItem.NUM)
进入g
来自g.DefaultIfEmpty()中的gItem
其中gItem==null
选择cItem.ToList();
列表removedItemsList=(
从storedItems中的sItem
在currentItems中加入cItem
on(sItem.YEAR+sItem.NUM)等于(cItem.YEAR+cItem.NUM)
进入g
来自g.DefaultIfEmpty()中的gItem
其中gItem==null
选择sItem.ToList();
}
当前解决方案:
List<string> criteria = (from item in currentItemList select item.YEAR + item.NUM).ToList();
foreach(AMENDMENT a in storedItems)
{
if(!criteria.Contains(a.YEAR + a.NUM))
//do stuff here
}
List<string> criteria = (from item in currentItemList select item.YEAR + item.NUM).ToList();
foreach(AMENDMENT a in storedItems)
{
if(!criteria.Contains(a.YEAR + a.NUM))
//do stuff here
}
List-criteria=(从currentItemList中的项选择item.YEAR+item.NUM);
foreach(storedItems中的修订a)
{
如果(!criteria.Contains(a.YEAR+a.NUM))
//在这里做事
}
因此,基本上,我没有在LINQ中执行条件语句,而是在for循环中的if语句中执行。老实说,我认为这很难看,但它有两个好处
但是,如果其他人有建议,我仍然愿意听取意见。我已经编辑了您的标题。请参阅“”,其中共识是“不,他们不应该”。为什么它适用于newItems查询而不适用于removedItems查询?它们本质上是相同的查询?我在您的答案中看到的唯一区别是您在LINQ查询中向storedItems对象添加了
ToList()
。这样做会产生错误:无法将类型“System.Collections.Generic.IEnumerable”隐式转换为“System.Linq.IQueryable”。存在显式转换(您是否缺少转换?
您的答案中是否有我缺少的内容?我认为第二个答案可能有效,但这只是因为它现在仅限于我们检查的一个字段。我希望有一个没有这个限制的解决方案。例如,如果我不仅仅关心2013.OK,我可以说LIST itemIds=from x in currentItems选择x.YEAR+x.NUM
,然后使用代码片段:!itemIds.Contains(item.YEAR+item.NUM)
因此,您的解决方案可以使用多个字段进行比较。但是,似乎应该有一种更干净的方法来实现这一点,比如SQL中的MERGE语句。经过进一步测试,您的第二个解决方案会在(sItem.YEAR+sItem.NUM)上生成与第一个解决方案相同的错误等于(cItem.YEAR+cItem.NUM)与sItem.YEAR等于cItem.YEAR&&sIteam.NUM等于cItem.NUM上的相同还是我遗漏了什么?我恰好遗漏了什么。LINQ讨厌我们,不让我们在两个领域加入lol:)