2016-08-31 5 views
0

Я использую Linq-to-Xml для создания двух IEnumerables, но я хочу объединить результаты второго списка с первым списком. Когда я использую .Concat() я получаю следующее сообщение об ошибке:Как присоединиться к двум IEnumerables с анонимными типами?

'IQueryable<>' does not contain a definition for 'Concat' and the best extension method overload 'ParallelEnumerable.Concat<>(ParallelQuery<>, IEnumerable<>)' requires a receiver of type 'ParallelQuery<>'

Два списка Я пытаюсь .Concat() здесь:

var findingDetails = from f in element.Elements(ns + "Group") 
        select new 
        { 
         testID = (string)f.Attribute("id").Value, 
         title = (string)f.Element(ns + "title"), 
         idrefFD = (string)f.Element(ns + "Rule").Attribute("id").Value, 
         severity = (string)f.Element(ns + "Rule").Attribute("severity").Value, 
         description = (string)f.Element(ns + "Rule").Element(ns + "description"), 
         fixText = (string)f.Element(ns + "Rule").Element(ns + "fixtext") 
        }; 
var getStatus = from gs in element.Descendants(ns + "rule-result") 
       select new 
       { 
        idrefStatus = (string)gs.Attribute("idref").Value, 
        result = (string)gs.Element(ns + "result"), 
        dateTime = (string)gs.Attribute("time") 
       }; 

Ошибка генерируется на findingDetails использования здесь:

var combined = findingDetails.Concat(getStatus); 

То, что я пытаюсь получить, это var, у которого есть все: от findingDetails + getStatus.result и getStatus.dateTime, в одном месте. Поэтому мне нужно только перебрать один цикл foreach(), чтобы получить доступ ко всем значениям вместо использования вложенного цикла foreach().

Пример XML документа:

<?xml version="1.0" encoding="UTF-8"?> 

<cdf:Benchmark style="SCAP_1.1" resolved="1" id="RHEL_6_STIG" xsi:schemaLocation="http://checklists.nist.gov/xccdf/1.1 http://nvd.nist.gov/schema/xccdf-1.1.4.xsd http://cpe.mitre.org/dictionary/2.0 http://scap.nist.gov/schema/cpe/2.2/cpe-dictionary_2.2.xsd" xmlns:cdf="http://checklists.nist.gov/xccdf/1.1" xmlns:cpe="http://cpe.mitre.org/dictionary/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xhtml="http://www.w3.org/1999/xhtml"> 
    <cdf:status date="2016-04-22">accepted</cdf:status> 
    <cdf:title>Red Hat Enterprise Linux 6 Security Technical Implementation Guide</cdf:title> 
    <cdf:description>The Red Hat Enterprise Linux 6 Security Technical Implementation Guide (STIG) is published as a tool to improve the security of Department of Defense (DoD) information systems. Comments or proposed revisions to this document should be sent via e-mail to the following address: [email protected]</cdf:description> 
    <cdf:notice id="terms-of-use"></cdf:notice> 
    <cdf:reference href="http://iase.disa.mil"> 
     <dc:publisher>DISA</dc:publisher> 
     <dc:source>STIG.DOD.MIL</dc:source> 
    </cdf:reference> 
    <cdf:plain-text id="release-info">Release: 11 Benchmark Date: 22 Apr 2016</cdf:plain-text> 
    <cdf:platform idref="cpe:/o:redhat:enterprise_linux:6"></cdf:platform> 
    <cdf:version>1</cdf:version> 
    <cdf:Profile id="MAC-1_Classified"> 
     <cdf:title>I - Mission Critical Classified</cdf:title>    
    </cdf:Profile> 
    <cdf:Value id="var_umask_for_daemons"> 
     <cdf:title>daemon umask</cdf:title> 
     <cdf:description>Enter umask for daemons</cdf:description> 
     <cdf:value>022</cdf:value> 
     <cdf:value selector="022">022</cdf:value> 
     <cdf:value selector="027">027</cdf:value> 
    </cdf:Value> 
    <cdf:Group id="V-7055"> 
     <cdf:title>APPNET0031 No Strong Name Verification</cdf:title> 
       <cdf:description>&lt;GroupDescription&gt;&lt;/GroupDescription&gt;</cdf:description> 
      <cdf:Rule weight="10.0" id="SV-7438r2_rule" severity="medium"> 
        <cdf:version>APPNET0031</cdf:version> 
        <cdf:title>Digital signatures assigned to strongly named assemblies must be verified.</cdf:title> 
        <cdf:description>&lt;VulnDiscussion&gt;A strong name consists of the assembly's identity, simple text name, version number, and culture information (if provided)—plus a public key and a digital signature. Strong names serve to identify the author of the code. If digital signatures used to sign strong name assemblies are not verified, any self signed code can be impersonated. This can lead to a loss of system integrity. &lt;/VulnDiscussion&gt;&lt;FalsePositives&gt;&lt;/FalsePositives&gt;&lt;FalseNegatives&gt;&lt;/FalseNegatives&gt;&lt;Documentable&gt;false&lt;/Documentable&gt;&lt;Mitigations&gt;&lt;/Mitigations&gt;&lt;SeverityOverrideGuidance&gt;&lt;/SeverityOverrideGuidance&gt;&lt;PotentialImpacts&gt;&lt;/PotentialImpacts&gt;&lt;ThirdPartyTools&gt;&lt;/ThirdPartyTools&gt;&lt;MitigationControl&gt;&lt;/MitigationControl&gt;&lt;Responsibility&gt;System Administrator&lt;/Responsibility&gt;&lt;IAControls&gt;DCSL-1&lt;/IAControls&gt;</cdf:description> 
        <cdf:reference> 
         <dc:publisher>DISA</dc:publisher> 
         <dc:identifier>2030</dc:identifier> 
         <dc:type>DPMS Target</dc:type> 
        </cdf:reference> 
        <cdf:fixtext fixref="F-12596r7_fix">Use regedit to remove the values stored in Windows registry key hKLM\Software\Microsoft\StrongName\Verification. There should be no assemblies or hash values listed under this registry key. All assemblies must require strong name verification in a production environment. Strong name assemblies that do not require verification in a development or test environment must have documented approvals from the IAO.</cdf:fixtext> 
        <cdf:fix id="F-12596r7_fix"></cdf:fix> 
        <cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5"> 
         <cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:2"></cdf:check-content-ref> 
        </cdf:check> 
      </cdf:Rule> 
     </cdf:Group> 
     <cdf:TestResult start-time="2016-07-20T11:59:59" version="1" test-system="cpe:/a:spawar:scc:4.1" end-time="2016-07-20T12:00:50" id="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-xccdf.xml---MAC-2_Classified-1"> 
      <cdf:benchmark href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-xccdf.xml"></cdf:benchmark> 
      <cdf:organization>SPAWAR Systems Center Atlantic</cdf:organization> 
      <cdf:identity privileged="true" authenticated="true">CCSAdmin</cdf:identity> 
      <cdf:profile idref="MAC-2_Classified"></cdf:profile> 
      <cdf:target>hostname</cdf:target> 
      <cdf:target-address>192.168.1.000</cdf:target-address> 
      <cdf:target-facts> 
        <cdf:fact name="urn:scap:fact:asset:identifier:host_name" type="string">hostname</cdf:fact> 
        <cdf:fact name="urn:scap:fact:asset:identifier:domain" type="string">.net</cdf:fact> 
        <cdf:fact name="urn:scap:fact:asset:identifier:fqdn" type="string">hostname.net</cdf:fact> 
        <cdf:fact name="urn:scap:fact:asset:identifier:os_name" type="string">Windows 7 Enterprise</cdf:fact> 
        <cdf:fact name="urn:scap:fact:asset:identifier:os_service_pack" type="string">Service Pack 1</cdf:fact> 
        <cdf:fact name="urn:scap:fact:asset:identifier:ipv4" type="string">192.168.1.000</cdf:fact> 
      </cdf:target-facts> 
      <cdf:platform idref="cpe:/a:microsoft:.net_framework:4.0"></cdf:platform> 
      <cdf:rule-result version="APPNET0031" time="2016-07-20T11:59:59" idref="SV-7438r2_rule" weight="10.0" severity="medium"> 
        <cdf:result>pass</cdf:result> 
        <cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5"> 
         <cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:2"></cdf:check-content-ref> 
        </cdf:check> 
      </cdf:rule-result> 
      <cdf:rule-result version="APPNET0046" time="2016-07-20T11:59:59" idref="SV-7444r3_rule" weight="10.0" severity="medium"> 
        <cdf:result>fail</cdf:result> 
        <cdf:fix id="F-12602r12_fix"></cdf:fix> 
        <cdf:check system="http://oval.mitre.org/XMLSchema/oval-definitions-5"> 
         <cdf:check-content-ref href="U_Microsoft_DotNet_Framework_4_V1R4_STIG_SCAP_1-1_Benchmark-oval.xml" name="oval:mil.disa.fso.dotnet:def:15"></cdf:check-content-ref> 
        </cdf:check> 
      </cdf:rule-result> 
     </cdf:TestResult> 
</cdf:Benchmark> 

Я изменил запросы и теперь оба выглядят так:

var findingDetails = from f in element.Elements(ns + "Group") 
           select new 
           { 
            idrefStatus = (string)"", 
            result = (string)"", 
            dateTime = (string)"", 
            testID = (string)f.Attribute("id").Value, 
            title = (string)f.Element(ns + "title"), 
            idref = (string)f.Element(ns + "Rule").Attribute("id").Value, 
            severity = (string)f.Element(ns + "Rule").Attribute("severity").Value, 
            description = (string)f.Element(ns + "Rule").Element(ns + "description"), 
            fixText = (string)f.Element(ns + "Rule").Element(ns + "fixtext")           
           }; 
      var getStatus = from gs in element.Descendants(ns + "rule-result") 
          select new 
          { 
           idrefStatus = (string)gs.Attribute("idref").Value, 
           result = (string)gs.Element(ns + "result"), 
           dateTime = (string)gs.Attribute("time"), 
           testID = (string)"", 
           title = (string)"", 
           idref = (string)"", 
           severity = (string)"", 
           description = (string)"", 
           fixText = (string)"" 
          }; 

var combined = findingDetails.Concat(getStatus); 

Но теперь выход выглядит так

foreach (var cf in combined) 
{ 
    Console.WriteLine(cf.idref + ", " + cf.result); 
} 

SV-7438r2_rule, 
SV-7444r3_rule, 
SV-40966r1_rule, 
SV-41075r1_rule, 
, pass 
, fail 
, pass 
, pass 

Принимая во внимание, я Я пытаюсь получить что-то вроде этого:

SV-7438r2_rule, pass 
SV-7444r3_rule, fail 
SV-40966r1_rule, pass 
SV-41075r1_rule, pass 
+2

типы не совпадают ... как они должны быть сцеплены за исключением литья последовательностей 'object' или' dynamic' ? прочитайте: https://msdn.microsoft.com/en-us/library/bb397696.aspx * Поскольку методы Equals и GetHashCode для анонимных типов определены в терминах методов Equals и GetHashCode свойств, два экземпляра тот же анонимный тип равен только в том случае, если все их свойства равны. * –

+1

Вы пытаетесь объединить их, а не конкатенировать их? Вы не можете объединить две коллекции разных типов. –

+0

Конечно, можно конкатенировать коллекции анонимных типов, но только если * они имеют все те же поля * (типы и имена). Нет. Как бы вы даже рассчитывали на их конкатенацию? Что вы ожидаете от результата? –

ответ

0

С ожидаемого выхода («Принимая во внимание, что я пытаюсь получить что-то вроде этого: ...») и данные, которые вы добавили, похоже, что вы ищете является join и не concat списков (CONCAT даст вам н * м записи)

Это то, что, кажется, вы ищете :

XNamespace ns = "http://checklists.nist.gov/xccdf/1.1"; 
var findingDetails = (from f in XDocument.Load("data.xml").Descendants(ns + "Group") 
         let rule = f.Element(ns + "Rule") 
         select new 
         { 
          testID = (string)f.Attribute("id").Value, 
          title = (string)f.Element(ns + "title"), 
          idref = (string)rule.Attribute("id").Value, 
          severity = (string)rule.Attribute("severity").Value, 
          description = (string)rule.Element(ns + "description"), 
          fixText = (string)rule.Element(ns + "fixtext") 
         }).ToList(); 
var getStatus = (from gs in XDocument.Load("data.xml").Descendants(ns + "rule-result") 
        select new 
        { 
        idrefStatus = (string)gs.Attribute("idref").Value, 
        result = (string)gs.Element(ns + "result"), 
        dateTime = (string)gs.Attribute("time"), 
        }).ToList(); 

var result = (from d in findingDetails 
       join f in getStatus on d.idref equals f.idrefStatus 
       select new { d, f }).ToList(); 

Если вы, возможно, Group S, которые не имеют соответствия rule-result затем использовать left join вместо

+1

Gilad, Спасибо! Еще раз. Это была занятая работа, изучающая все эти вещи. – Chris

+0

@Chris - рад помочь :) –

+0

Вы можете немного оптимизировать это, чтобы избежать многократного поиска «правила», выполняя что-то вроде 'let rule = f.Element (ns +« Rule »)', а затем 'idref = (string) rule.Attribute («id»). Значение « –

0

Вы можете конкатенировать два анонимных типа, если они объявлены с точно такими же свойствами.

Вы не можете Concat двух различных типов, но вы можете бросить их object, а затем CONCAT:

List<int> ints = new List<int>() { 1, 2, 3 }; 
List<string> strings = new List<string> { "a", "b", "c" }; 

ints.Cast<object>().Concat(strings.Cast<object>());