我上了汽车课
[Serializable]
public class Car
{
public Driver Driver = new Driver();
public List<Driver> Drivers = new List<Driver>();
}
[Serializable]
public class Driver
{
public int Id { get; set; }
}
当我尝试序列化此类的一个象元然后转换为数据集时,我得到了一个非常奇怪的行为:
void Main()
{
var x = new Car();
x.Drivers.Add(new Driver { Id = 1 });
var dataSet= AsDataSet(x);
dataSet.Tables["Driver"].Rows.Count;//2!! and two columns: Id and Driver_Id
dataSet.Tables["Drivers"].Rows.Count;//1 and only one column Driver_Id
}
static DataSet AsDataSet(Car ceInv)
{
var serializer = new XmlSerializer(ceInv.GetType());
var ms = new MemoryStream();
serializer.Serialize(ms, ceInv);
ms.Position = 0;
var ds = new DataSet();
ds.ReadXml(ms);
return ds;
}
有人可以告诉我为什么表Drivers为空并且没有ID列吗? 不幸的是,属性Driver应该保持这种状态(旧版代码)。我只能更改属性Drivers。 更改驱动程序属性的名称不会对结果产生影响。
答案 0 :(得分:0)
看看您的DataSet
的序列化表示形式,这应该很明显。
<?xml version="1.0"?>
<Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Driver>
<Id>0</Id>
</Driver>
<Drivers>
<Driver>
<Id>1</Id>
</Driver>
</Drivers>
</Car>
您如何期望ReadXml()
方法区分第一个<Driver>
元素和<Drivers>
元素内的元素?它们似乎是同一张表的一部分。
您还将在Driver
类中使用空Car
实例化一个新的Id
,不确定是否是故意的。
无论如何,我会让您的属性名称不那么模棱两可,以便ReadXml()
可以解决问题。例如,将Driver
中的单个Car
属性更改为PrimaryDriver
或类似名称。
我知道您说您不能更改该属性,所以唯一的解决方案是自定义XML序列化程序,但这可能无法为您提供所需的DataSet
。
void Main()
{
var x = new Car();
x.Drivers.Add(new Driver { Id = 1 });
var dataSet = AsDataSet(x);
Console.WriteLine($"PrimaryDriver: {dataSet.Tables["PrimaryDriver"].Rows.Count}");
Console.WriteLine($"Drivers: {dataSet.Tables["Drivers"].Rows.Count}");
// Output:
// PrimaryDriver: 1
// Drivers: 1
}
[Serializable]
public class Car
{
public Driver PrimaryDriver = new Driver();
public List<Driver> Drivers = new List<Driver>();
}
[Serializable]
public class Driver
{
public int Id { get; set; }
}
private static DataSet AsDataSet(Car ceInv)
{
var serializer = new XmlSerializer(ceInv.GetType());
var ms = new MemoryStream();
serializer.Serialize(ms, ceInv);
ms.Position = 0;
var ds = new DataSet();
//Console.WriteLine($"{new StreamReader(ms).ReadToEnd()}"); ms.Position = 0; // DEBUGGING
ds.ReadXml(ms);
return ds;
}
答案 1 :(得分:0)
根据我在重命名Car
类中的一个/两个属性后所看到的内容,看来ReadXml()
会根据使用的类型而不只是属性来推断架构。考虑以下;将Car
的定义更改为
[Serializable]
public class Car
{
public Driver Someone { get; set; } = new Driver { Id = 47 }; // I did this so I could identify the rows
public List<Driver> Dudes { get; set; } = new List<Driver>();
}
我最终在数据集中得到了3个表。有人,帅哥和司机。单个属性按预期存储在为该属性命名的表中。另一方面,list属性会创建一个以该类型命名的表,在本例中为Driver
,在您的情况下是另一个以属性Drivers
命名的表,在我的情况下为Dudes
List<Driver>
属性的数据存储在驱动程序表中。该属性与以该属性命名的表之间存在关系。