代码块四(下面)给我一个错误,我在修复方面感到茫然...
这是我正在使用的XML Schema:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!DOCTYPE ctqcfg SYSTEM "cache.dtd">
<cache version="1.0">
<configuration name="Test">
<cacheControl>
<cache name="Customer" mode="off"/>
<cache name="Vendor" mode="off"/>
<cache name="Agency" mode="off"/>
<cache name="Partner" mode="off"/>
</cacheControl>
</configuration>
<configuration name="Production">
<cacheControl>
<cache name="Customer" mode="preload"/>
<cache name="Vendor" mode="dynamic"/>
<cache name="Agency" mode="dynamic"/>
<cache name="Partner" mode="dynamic"/>
</cacheControl>
</configuration>
</cache>
加载XML文件
Private XElement As XElement = Nothing
Public Sub Load()
XElement = XElement.Load(ConfigurationResource)
End Sub
当用户选择要编辑的配置时,将保留对所选配置元素的根的引用
Private ConfigurationRoot As System.Collections.Generic.IEnumerable(Of System.Xml.Linq.XElement)
Private ConfigurationName_ As String
Public Property ConfigurationName() As String
Get
Return ConfigurationName_
End Get
Set(ByVal Value As String)
ConfigurationName_ = Value
ConfigurationRoot = From Configuration In XElement.<configuration> Where Configuration.@name = Value
End Set
End Property
尝试检索与缓存名称相对应的缓存模式(在本例中为Customer)
Public Property CustomerCache() As String
Get
Try
Return From Cache In ConfigurationRoot.<cacheControl>.<cache> Where Cache.@name = "Customer" Select Cache.@mode
Catch Exception As Exception
Return Nothing
End Try
End Get
Set(ByVal Value As String)
'ToDo
End Set
End Property
我收到以下错误
System.InvalidCastException was caught
Message=Unable to cast object of type 'WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String]' to type 'System.String'.
这是我使用LINQ的第一天,我似乎对如何访问该属性有一个基本的误解 - 似乎查询返回了一个集合,我知道只有一个可能的值可以找到...
答案 0 :(得分:1)
您需要.First()
或.Single()
:
Return (From Cache In ConfigurationRoot.<cacheControl>.<cache> Where Cache.@name = "Customer" Select Cache.@mode).First()
答案 1 :(得分:0)
前三个代码块都实现了相同的结果,但访问属性内容的方法略有不同:
Return "true" = (From DBConnections In Configurations.<dbConnection> Where "Customization" = DBConnections.@name Select DBConnections.<password>.@encrypted).Single
Dim Element As IEnumerable(Of XElement) = (From DBConnections In Configurations.<dbConnection> Where "Customization" = DBConnections.@name Select DBConnections.<password>).Single
Return "true" = Element(0).@encrypted
前面的例子轻轻地误导我们,因为.Single引用明确指出将会找到一个且只有一个 - 但实际上我们必须处理一个集合的结果(只有一个项目)。与方法1相比,它更加令人困惑,我们不必明确处理集合来检索属性值。
Dim Element As XElement = ((From DBConnections In Configurations.<dbConnection> Where "Customization" = DBConnections.@name Select DBConnections.<password>).Single)(0)
Return "true" = Element.@encrypted
最后一个例子通过引用集合中的第一个项目并将其存储在内部,努力处理必须处理集合(一个项目)以尽快检索集合中的项目的误导性部分。适当的类型,以便我们可以不再担心集合,而是处理我们真正感兴趣的对象(在本例中是一个XElement对象)。
Dim Element As XElement = ((From DBConnections In Configurations.<dbConnection> Where "Customization" = DBConnections.@name Select DBConnections.<password>).Single)(0)
If Value Then
Element.@encrypted = "true"
Else
Element.@encrypted = "false"
End If
使用三种查询方法有助于澄清我的心理模型,了解LINQ返回的内容。另外,我需要了解这里真正要修改“加密”属性...