Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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
.net 获取IQueryable集合之间的差异_.net_Sql_Linq_Entity Framework - Fatal编程技术网

.net 获取IQueryable集合之间的差异

.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

我有一张三列的桌子。两列组成PK。该表存储有关目录中文件的信息

我有一个文件目录作为输入

目标是获得添加和删除文件的列表

我有以下代码:

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语句中执行。老实说,我认为这很难看,但它有两个好处

  • 它起作用了

  • 不像LINQ查询那样需要大约3秒钟,它需要几百分之一秒


  • 你试过先投影吗?如果你的数据量不是太大,它不会杀死你。否则,你需要更具创造性

    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语句中执行。老实说,我认为这很难看,但它有两个好处

  • 它起作用了

  • 不像LINQ查询那样需要大约3秒钟,它需要几百分之一秒


  • 但是,如果其他人有建议,我仍然愿意听取意见。

    我已经编辑了您的标题。请参阅“”,其中共识是“不,他们不应该”。为什么它适用于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:)