2011-10-07 88 views
0

这里集和项目之间变化的LINQ检索项目是我的课:尚未在台

public class XDetail 
{ 
    public string Name { get; set; } 
    public int ID { get; set; } 
} 

public class X 
{ 
    public int XID { get; set; } 
    public int ID { get; set; } 
} 

的ID在它们之间共享链接X和XDetail(一对多的关系)和X和XDetail是真正键入DataRows。我在使用下面的LINQ查询文件中读取并塑造一个匿名类型:

var results = (from line in File.ReadAllLines(file) 
       select new 
       { 
        XID = int.Parse(line.Substring(0, 8).TrimStart('0')), 
        Name = line.Substring(8, 255).Trim() 
       }).ToList(); 

这个数据是用来检查对现有X/XDetail做出适当的修改或添加新记录。我将结果包装在一个检查中,以查看序列没有结果时是否抛出.ToList()。 XList是一个列表,XDetailList是一个列表。

从那里我试图看中LINQ查询来匹配合适的项目:

var changedData = from x in XList 
        join xDetail in XDetailList on x.ID equals xDetail.ID 
        where 
        (!results.Any(p => p.XID.Equals(x.XID)) 
        || !results.Any(p => p.Name.Equals(xDetail.Name)))     
        select new 
        {      
         XValue = x, 
         XDetailValue = xDetail, 
         Result = (from result in results 
           where result.Name.Equals(xDetail.Name) 
           select result).SingleOrDefault() 
        }; 

我的新问题是,这个查询将只提供给我什么X/XDetail已经改变,也不是什么新。为了完成新功能,我必须运行另一个查询,这个查询在小数据集(X/XDetail的3个已有条目)上测试时似乎已经足够了,但是当我尝试真正的文件并通过〜7700个条目有无尽的处理。

对于已经包含在X/XDetail以下的样品数据集:
XID:1,名称:鲍勃,ID:10
XID:2,名称:乔,ID:20
XID:3 ,名称:山姆,ID:30

与含有结果的文件:
XID:2,名称:Bob2
XID:3,名称:NotSam
XID:4,名称:NewGuy
XID:5 ,名称:NewGuy2

我希望能够得到含有结果集:
{XID:2,名称:Bob2},X,xDetail
{XID:3,名称:NotSam},X,xDetail
{ XID:4,名称:NewGuy},X,xDetail
{XID:5,名称:NewGuy2},X,xDetail

我想x和xDetail如设定为使得我可以使用结果的一部分那些键入的数据行进行必要的更改。

我想我的手在做这样的查询:

var newData = from result in results 
       join x in XList on result.XID equals x.XID 
       join xDetail in XDetailList on x.ID equals xDetail.ID 
         where 
         (x.XID == result.XID && xDetail.Name != result.Name) 
         select new 
         { 
          XValue = x, 
          XDetailValue = xDetail, 
          Result = result 
         }; 

由于加入表明我只有永远会得到的数据更改的项目,我真的希望能够在增加数据不在X/XDetail中,并停止我的系统在过去2.5小时内处理了我的〜7700更改文件。我觉得我已经注意到了这一点以及相关的查询太长时间,无法找到我应该怎样做正确的where子句。

有没有一种方法来构建linq查询来查找更改后的数据和X/XDetail中不存在的数据,并将其返回到新的结果集中进行处理?

+0

这是什么问题? –

+0

有没有一种方法来构建linq查询来查找更改后的数据以及X/XDetail中不存在的数据,并将其返回到要处理的新结果集中? – ShelbyZ

回答

2

我认为你的表现问题与你的查询的复杂性有关,可能在O(n^2)左右。

因此,首先,我建议您设置的当前数据的查找结构,像这样(*):

var joinedByXID = (from x in XList 
        join xDetail in XDetailList on x.ID equals xDetail.ID 
        select new { X = x, XDetail = xDetail }) 
        .ToLookup(x => x.X.ID); 

现在,我不知道,但我认为,说“改变数据“你的意思是已经存在XID但有新名字的条目列表,是不是?通过“新数据”你指的是具有新的XID(XID当前不存在的Xlist/XDetailList)项的列表

var changedData = results 
.Where(r => joinedByXID.Contains(r.XID)) 
.SelectMany(r => joinedByXID[r.XID] 
      .Where(x => x.XDetail.Name != r.Name) 
      .Select(old => new {XValue=old.X, XDetailValue=old.XDetail, Result=r})); 

然后,如果:
如果是这样,你可以得到“改变数据”使用此查询,但是你不能用X/Xdetail元素配合他们,因为,根本就没有什么,所以这是简单的:

var newData = results 
.Where(r => !joinedByXID.Contains(r.XID)); 

(*)
其实,要更快,你可以安排你的数据在字典的字典中,外键是XI​​D内部键是名称。

+0

..就像老板.. – Bastardo