Define a function `lookup` to look up the `B` value from `ds2` via the `ID` key:

    lookup[x_] := Query[SelectFirst[#ID == x &], "B"]@ds2

then replace the missing values,

    SortBy["ID"]@ds3[All, <|#,"B" -> Replace[#B, Missing["Unmatched"] -> lookup[#ID]]|> &]

or just lookup the `B` value in all rows of `ds3` from `ds2`,

    SortBy["ID"]@ds3[All, <|#, "B" -> lookup[#ID]|> &]


[![enter image description here][1]][1]


  [1]: https://i.sstatic.net/Cko5S.png