【问题标题】:Linq to Entities and Linq to XMLLinq to Entities 和 Linq to XML
【发布时间】:2011-01-20 18:49:21
【问题描述】:

给定以下 XDocument 形式的 XML 结构:

<Header><person><ID>0888-123-45</ID><Name>Joe</Name><LocationID>Loc1</LocationID><LocationName>New York</LocationName><CarName>Honda</CarName><CarYear>2000</CarYear></person><person><ID>199-20-333</ID><LocationID>My House</LocationID><LocationName>My House</LocationName><CarName>BMW</CarName><CarYear>2011</CarYear></person></Header>

涉及 3 个实体:

人物

  • GUID、ID (varchar)、名称 (varchar)、LocationID(位置的 GUID)

汽车

  • GUID、PersonID(人员的 GUID)、CarName (varchar)、CarYear (varchar)

位置

  • GUID、LocationID (varchar)、LocatioName (varchar)

我想要实现的是以下步骤:

  1. 获取 XDocument 中所有人的不同位置
  2. 如果 XDocument 中的位置存在于数据上下文中,则不要插入,否则插入
  3. 插入所有人员及其对应的汽车。

这就是我所拥有的,它会引发错误,因为查询是 Linq to Entities 和 Linq to XML 的混合。我感谢任何洞察力和建议,以更好地解决它。没有 for 循环,因为用 for 循环解析 XDocument 很慢。

        Dim fileLocs = (From p In xmlDoc.<Header>.<Person>
                        Select New location With {.locID = Guid.NewGuid(), _
                                                  .locationID = If(p.<LocationID> Is Nothing, Nothing, p.<LocationID>.Value), _
                                                  .locLabel = If(p.<LocationName> Is Nothing, Nothing, p.<LocationName>.Value)})
        Dim filteredFileLocs = From l In fileLocs
                               Where l.locationID IsNot Nothing AndAlso l.locationID <> "" AndAlso
                                    (From loc In ctx.locations
                                      Where loc.locationID = l.locationID AndAlso loc.locLabel = l.locLabel
                                      Select loc).Count = 0
                              Select l

        Dim sysLocs = (From loc In ctx.locations Select loc)
        Dim allLocs = filteredFileLocs.Union(sysLocs)

        Dim pers As IEnumerable(Of person) = (From p In xmlDoc.<Header>.<Person>
                                            Select New Person With {.personID = Guid.NewGuid(), .ID = p.Element(XName.Get("ID")).Value, _
                                                                    .locID = If(p.<locationID> IsNot Nothing AndAlso p.<locationID>.Value <> "", CType(Nothing, Guid?), _
                                                                                    (From sl In allLocs
                                                                                    Where sl.locationID = p.Element(XName.Get("LocationID")).Value AndAlso
                                                                                        sl.locLabel = p.Element(XName.Get("LocationName")).Value
                                                                                    Select sl.locID)), _
                                                                    .Name = p.Element(XName.Get("Name")).Value})


        For Each l In filteredFileLocs
            ctx.locations.AddObject(l)
        Next
        For Each p In pers
            ctx.persons.AddObject(p)
        Next

错误出现在 Dim pers: "Specified cast is not valid."

【问题讨论】:

    标签: linq-to-entities linq-to-xml


    【解决方案1】:

    我注意到的是设置 .locID 的子句,

    (From sl In allLocs Where sl.locationID = p.Element(XName.Get("LocationID")).Value
    
    AndAlso sl.locLabel = p.Element(XName.Get("LocationName")).Value Select sl.locID)
    

    正在返回一个 ienumberable,它被分配给 .LocID,它是一个 GUID,所以这应该是错误原因,您需要像这样添加 FirstOrDefault、First、SingleOrDefault 或 Single

    (From sl In allLocs Where sl.locationID = p.Element(XName.Get("LocationID")).Value
    
    AndAlso sl.locLabel = p.Element(XName.Get("LocationName")).Value _
    
    Select sl.locID).FirstOrDefault()
    

    【讨论】:

    • 你是对的。谢谢!另外,我如何找出汽车属于哪个人是首先为每个人插入 GUID 的 XElement,然后在初始化所有汽车时,我会这样做:.PersonID = GUID.Parse(c.Parent..Value)。更好的解决方案总是受欢迎的!
    猜你喜欢
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    相关资源
    最近更新 更多