Используя XmlSerializer с частными и общедоступными свойствами константы

Ваши таблицы 1-1 или 1-много? Если они один ко многим, то ваши объединения приведут к появлению гораздо большего количества строк, чем вы, вероятно, хотите. Если это так, один из вариантов - сначала выполнить groupBy для каждой таблицы, к которой вы собираетесь присоединиться. Рассмотрите этот пример:

val df1 = Seq(1, 2).toDF("id")
val df2 = Seq(
  (1, "a", true),
  (1, "b", false),
  (2, "c", true)
).toDF("id", "C2", "B2")

val df3 = Seq(
  (1, "x", false),
  (1, "y", true),
  (2, "z", false)
).toDF("id", "C3", "B3")

// Left outer join without accounting for 1-Many relationship.  Results in cartesian
// joining on each ID value!
df1.
  join(df2, Seq("id"), "left_outer").
  join(df3, Seq("id"), "left_outer").show()

+---+---+-----+---+-----+
| id| C2|   B2| C3|   B3|
+---+---+-----+---+-----+
|  1|  b|false|  y| true|
|  1|  b|false|  x|false|
|  1|  a| true|  y| true|
|  1|  a| true|  x|false|
|  2|  c| true|  z|false|
+---+---+-----+---+-----+

В качестве альтернативы, если вы группируете строки перед объединением, чтобы ваши отношения всегда 1-1, вы не получите добавляемых записей

val df2Grouped = df2.groupBy("id").agg(collect_list(struct($"C2", $"B2")) as "df2")
val df3Grouped = df3.groupBy("id").agg(collect_list(struct($"C3", $"B3")) as "df3")

val result = df1.
  join(df2Grouped, Seq("id"), "left_outer").
  join(df3Grouped, Seq("id"), "left_outer")
result.printSchema
result.show(10, false)

scala> result.printSchema
root
 |-- id: integer (nullable = false)
 |-- df2: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- C2: string (nullable = true)
 |    |    |-- B2: boolean (nullable = false)
 |-- df3: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- C3: string (nullable = true)
 |    |    |-- B3: boolean (nullable = false)


scala> result.show(10, false)
+---+-----------------------+-----------------------+
|id |df2                    |df3                    |
+---+-----------------------+-----------------------+
|1  |[[a, true], [b, false]]|[[x, false], [y, true]]|
|2  |[[c, true]]            |[[z, false]]           |
+---+-----------------------+-----------------------+
6
задан John Saunders 28 July 2009 в 21:31
поделиться

4 ответа

XmlSerializer только взгляды на общедоступные поля и свойства. При необходимости в большем количестве управления можно реализовать IXmlSerializable и сериализировать то, что Вы хотели бы. Конечно, сериализация константы не имеет большого смысла, так как Вы не можете десериализовать к константе.

16
ответ дан 8 December 2019 в 02:53
поделиться

Проверьте DataContractSerializer, представленный в.NET 3.0. Это также использует формат XML, и во многих отношениях, это лучше, чем XmlSerializer, включая контакт с частными данными. См. http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/ для полного сравнения.

Если у Вас только есть.NET 2.0, существует BinarySerializer, который может иметь дело с частными данными, но конечно это - двоичный формат.

4
ответ дан 8 December 2019 в 02:53
поделиться

Не имеет смысла рассматривать const участники, поскольку они не на экземпляр; но если Вы просто имеете в виду непубличных членов экземпляра: рассмотреть DataContractSerializer (.NET 3.0) - это подобно XmlSerializer, но может сериализировать непубличные свойства (хотя это, "подписываются").

Посмотрите здесь для больше.

2
ответ дан 8 December 2019 в 02:53
поделиться

Несмотря на то, что сериализовать частные свойства невозможно, вы можете сериализовать свойства с помощью внутреннего установщика, например этого:

public string Foo { get; internal set; }

Для этого вам необходимо предварительно сгенерировать сборку сериализации с sgen.exe и объявите эту сборку как друга:

[assembly:InternalsVisibleTo("MyAssembly.XmlSerializers")]
10
ответ дан 8 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: