如果我不列出属性,比较对象不起作用 [英] Compare-Object not working if I don't list the properties

查看:28
本文介绍了如果我不列出属性,比较对象不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 2 个要比较的 Excel 电子表格:

I have 2 Excel spreadsheets I am trying to compare:

$OleDbAdapter = New-Object System.Data.OleDb.OleDbDataAdapter "Select * from [Report$]","Provider=Microsoft.ACE.OLEDB.12.0;Data Source=S:\FIS-BIC Reporting\Report Output Files\Product-Marketing\TEST_XI\ECM - Pipeline by LOB_04182013_040544.xls;Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
$RowsReturned = $OleDbAdapter.Fill($DataTable)

$OleDbAdapter2 = New-Object System.Data.OleDb.OleDbDataAdapter "Select * from [Report$]","Provider=Microsoft.ACE.OLEDB.12.0;Data Source=S:\FIS-BIC Reporting\Report Output Files\Product-Marketing\ECM - Pipeline by LOB_04182013_074004.xls;Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
$RowsReturned2 = $OleDbAdapter2.Fill($DataTable2)

Compare-Object $DataTable $DataTable2 

它什么都不返回.我知道在第 6 列中,它们是不同的.如果我指定-property F6",它会返回差值.除非我指定属性,否则知道为什么不这样做吗?列数可能会有所不同(尽管比较中的每个文件都相同),因此具体指定属性将不起作用.

It returns nothing. I know that in the 6th column, they are different. If I specify "-property F6", it does return the difference. Any idea why it doesn't unless I specify the property? The number of columns can vary (though will be the same for each of the files in the comparison), so specifying the properties specifically won't work.

推荐答案

如果不指定 -Property 参数,Compare-Object 不会比较所有属性,它比较对两个对象调用 .ToString() 方法的结果.因此,Compare-Object $DataTable $DataTable2$DataTable1.ToString()$DataTable1.ToString() 进行比较..ToString() 方法在 DataTable 对象上调用时返回一个空字符串,因此报告没有区别.

If you don't specify the -Property parameter, Compare-Object doesn't compare all properties, it compares the results of invoking the .ToString() method on both objects. So, Compare-Object $DataTable $DataTable2 compares $DataTable1.ToString() with $DataTable1.ToString(). The .ToString() method returns an empty string when invoked on a DataTable object, so there is no difference to report.

例如:

$file1 = Get-Item somefilename
$file1 = Get-Item anotherfilename
Compare-Object $file1 $file2

这将返回两个文件的完整路径之间的差异,如下所示:

This will return the difference between the full paths of the two files, like this:

InputObject              SideIndicator
-----------              -------------
<path>\anotherfilename   =>
<path>\somefilename      <=

这是因为在 FileInfo 对象上调用 .ToString() 会返回其 FullName 属性,因此您正在比较文件的完整路径名.

That's because invoking .ToString() on a FileInfo object returns its FullName property, so you're comparing the files' full path names.

尽管 -Property 参数接受多个属性,但列出所有属性并不是解决方案.除了非常乏味之外,它不会给你想要的结果.如果列出多个属性,Compare-Object 比较所有属性的组合,如果列出的任何一个属性不同,则返回显示所有列出的属性的结果属性(相同的和不同的)作为单一差异.

Although the -Property parameter accepts multiple properties, listing all the properties is not the solution. Aside from being very tedious, it will not give you the results you want. If you list multiple properties, Compare-Object compares the combination of all the properties, and if any one of the listed properties is different, it returns a result showing all the listed properties (both ones that are the same and ones that are different) as a single difference.

您需要做的是遍历一个属性列表,并为每个属性调用一次 Compare-Object:

What you need to do is iterate over a list of properties, and invoke Compare-Object once for each property:

$properties = ($DataTable | Get-Member -MemberType Property | Select-Object -ExpandProperty Name)
foreach ($property in $properties) {
  Compare-Object $DataTable $DataTable2 -Property "$property" | Format-Table -AutoSize
}

  • 在大多数情况下,当比较两个对象的所有属性时,您需要使用 Get-Member -MemberType Properties,以便覆盖所有属性类型.但是,如果您要比较 DataTable 对象,最好使用 Get-Member -MemberType Property 以便您只比较与数据字段对应的属性,而不是 DataTable 对象的其他属性与数据无关.

    • In most cases, when comparing all properties of two objects, you'd want to use Get-Member -MemberType Properties, in order to get cover all property types. However, if you're comparing DataTable objects, you're better off using Get-Member -MemberType Property so that you're comparing only the properties corresponding to data fields, not other properties of the DataTable objects that have nothing to do with the data.

      假设列数与您所说的相同,或者至少 $DataTable2 中的列数不超过$DataTable.

      This is written assuming that the number of columns is the same, as you stated, or at least that the number of columns in $DataTable2 doesn't exceed the number of columns in $DataTable.

      如果您不能可靠地假设,则通过比较($DataTable | Get-Member -MemberType Property).Count,从具有更多列的任何一个派生$properties 数组($DataTable2 | Get-Member -MemberType Property).Count 并使用较大的属性.

      If you can't reliably assume that, derive the $properties array from whichever one has more columns, by comparing ($DataTable | Get-Member -MemberType Property).Count with ($DataTable2 | Get-Member -MemberType Property).Count and using the properties from whichever is greater.

      使用 Format-Table 很重要,它不仅仅是为了让事情看起来漂亮.如果您列出多个相同类型的对象(在本例中为数组),PowerShell 会记住第一个对象的格式,并将其用于所有后续对象,除非您明确指定格式.由于第一列的名称对于每个属性(即电子表格中的每一列)都不同,因此第一列对于除遇到的第一个差异之外的所有属性都是空的.

      Using Format-Table is important, it's not just there to make things look pretty. If you list multiple objects of the same type (in this case, arrays), PowerShell remembers the format of the first object, and uses it for all subsequent objects, unless you explicitly specify a format. Since the name of the first column will be different for each property (i.e., each column from the spreadsheet), the first column will be empty for all but the first difference encountered.

      -AutoSize 开关是可选的.就是只是为了让事情看起来很漂亮.但是您必须将结果通过管道传送到格式过滤器.如果您愿意,也可以使用 Format-List.

      The -AutoSize switch is optional. That is there just to make things look pretty. But you must pipe the results to a formatting filter. You can also use Format-List if you prefer.

      这篇关于如果我不列出属性,比较对象不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆