将对象序列化到数据库中,同时保持灵活性

时间:2009-12-01 02:21:16

标签: c# serialization

将对象序列化到数据库时应该采取什么方法,请记住对象属性会及时更改?

首先,我想确保我的所有对象都实现了一个接口,但是当一个接口丢失一个属性并获得另一个属性时会发生什么。恢复后数据库中现有的序列化数据发生了什么?

我应该使用抽象类或接口吗?人们使用的最佳方法。

谢谢

4 个答案:

答案 0 :(得分:2)

下面的部分实现可能会为您提供灵活存储和检索属性的一些想法。对于管理属性添加和删除,当您添加属性没有问题。删除属性时,您无法在将来创建该类型的新属性,但保留现有数据或删除与这些属性关联的所有数据。

/// <summary>
/// The data storage could look something like this
/// create table PersistedObject (ObjectId int )
/// create table PersistedProperty (PropertyId int , PropertyName varchar(50) )
/// create table Data (ValueId int, PropertyId int, SerializedValue image )
/// </summary>
interface IFlexiblePersistence
{
    object this[string propertyName] { get; set;}

    void Persist();

}

class Person : IFlexiblePersistence
{
    Dictionary<string, object> data;

    public Person(int personId)
    {
        data = PopulatePersonData(personId);
    }

    public object this[string propertyName]
    {
        get { return data[propertyName]; }

        set
        {
            data[propertyName] = value;
            Persist();
        }
    }

    public void Persist()
    {
        LoopThroughAllValuesAndSaveToDB();
    }
}

答案 1 :(得分:0)

物体的使用寿命是多少?如果它只是短期的,你可以使用数据集并动态更新属性。

答案 2 :(得分:0)

这是一个历史悠久的问题,没有一个正确答案。

这在很大程度上取决于数据在您的应用程序中的使用方式。您希望限制使用的RAM数量,以及数据库的预期最大尺寸。所有这些因素都会促使你走向或远离各种方法。

  1. This article讨论数据广告及其在特定应用中的使用情况。

  2. This article讨论了数据传输对象的使用。

  3. This forum discussion就数据传输对象与域建模提出了很多意见。

  4. 上述方法2和3与他的回复中列出的David Silva Smiths IFlexiblePersistence方法完全兼容。但是,您可能会使用更多内存,并且在执行“典型”DTO时会失去大部分性能提升。如果记忆和速度不是问题,他的方法可能会非常简单。

答案 3 :(得分:0)

这取决于你的“序列化”的含义(它是一个超载的术语)。如果您将现有对象表示为列,则表示ORM:EF,LINQ-to-SQL,NHibernate等。如果您将对象表示为单个varbinary(max) / varchar(max)

无论你做什么,都不要使用BinaryFormatter - 如果更改字段(例如,将常规属性更改为自动属性),这将中断。你需要一些基于契约的东西,其中大部分都可以随着变化而变化。建议:

  • XmlSerializer / DataContractSerializer / Json.NET(text)
  • protobuf-net(二进制,使用google的“协议缓冲区”有线格式)

通过上述内容,您通常可以使用相当标准的DTO;例如(与DataContractSerializer和protobuf-net兼容):

[DataContract]
public class Customer {
    [DataMember(Order=1)]
    public int {get;set;}

    [DataMember(Order=2)]
    public string Name {get;set;}
}

我不会因为类似的原因NetDataContractSerializer使用BinaryFormatter - 对于短期请求很好,但对存储不利。请注意,大多数序列化程序使用具体类,因为很少有输出中包含类型元数据(因此需要额外的配置才能将ICustomer绑定到Customer类。