C# 基于DB值序列化和反序列化属性

C# 基于DB值序列化和反序列化属性,c#,.net,serialization,xmlserializer,C#,.net,Serialization,Xmlserializer,我有一个简单的类,它有bool属性。此属性的“Get”逻辑执行存储过程,以从数据库返回位字段 然后序列化该类并将其保存到数据库中的XML字段中。它可以很好地保存类和bool属性,没有问题 我似乎遇到的问题是当我反序列化这个类时。该类的反序列化很好,但是当驱动bool字段的数据被更新时,该类似乎只识别XML中序列化的内容,而不返回数据库以获取新的bool值(不执行我的过程以获取新的更新位字段) 我的解决方案是将XmlIgnoreAttribute属性添加到此字段,这样它就不会首先序列化。但我想知道

我有一个简单的类,它有bool属性。此属性的“Get”逻辑执行存储过程,以从数据库返回位字段

然后序列化该类并将其保存到数据库中的XML字段中。它可以很好地保存类和bool属性,没有问题

我似乎遇到的问题是当我反序列化这个类时。该类的反序列化很好,但是当驱动bool字段的数据被更新时,该类似乎只识别XML中序列化的内容,而不返回数据库以获取新的bool值(不执行我的过程以获取新的更新位字段)

我的解决方案是将XmlIgnoreAttribute属性添加到此字段,这样它就不会首先序列化。但我想知道是否有人注意到了这一点和/或可以帮助我理解.NET XmlSerializer类的内部工作原理

谢谢

[XmlIgnoreAttribute]
    public bool IsUpdated
    {
        get
        {
            DataTable dtResults = mclsSQLServerTool.LoadDataTable("exec stp_RL_SEL_NameIsUpdated '" + mstrName + "'");
            bool blnIsUpdated = Convert.ToBoolean(dtResults.Rows[0]["RU_bitIsUpdated"]);

            return blnIsUpdated;

        }
    }

我认为这是对财产的滥用。属性后面应该很少或没有代码。如果此代码曾在客户机-服务器应用程序中使用,则可能会从客户机进行数据库调用。我建议将此更改为方法调用。如果要序列化结果,请将“Convert.ToBoolean”的结果存储在属性中。现在,属性值是什么就更清楚了

像这样的

public bool IsUpdated { get; private set; }

public bool IsDataUpdated()
{ 
     DataTable dtResults = mclsSQLServerTool.LoadDataTable("exec stp_RL_SEL_NameIsUpdated '" + mstrName + "'"); 
     IsUpdated = Convert.ToBoolean(dtResults.Rows[0]["RU_bitIsUpdated"]); 

     return IsUpdated; 
} 

这里首先要注意的是,
[XmlIgnore]
是冗余的
XmlSerializer
对只获取属性(列表除外)不感兴趣,因为它知道它不能反序列化它们。例如:

public class SomeType
{
    public string Foo { get; set; }
    public string Bar { get { Console.WriteLine("get_Bar"); return "abc"; } }

    static void Main()
    {
        var ser = new XmlSerializer(typeof (SomeType));
        ser.Serialize(Console.Out, new SomeType { Foo = "def" });
    }
}
输出(减去名称空间、别名等):


def
(请注意,
Bar
未被调用)

对于反序列化,过程(对于简单值,而不是列表)很简单:当在传入的xml流中找到值时,将它们解析为成员,并分配它们-即xml反序列化器基本上是基于传入xml节点的美化开关语句

除非数据在传入的xml中(并且属性是读/写的),否则它永远不会随机调用“set”;当它这样做时,它期望分配一个值

在您的场景中,有趣的是,您的“get”不会在任何地方分配值—没有缓存。所以实际上,
XmlSerializer
不碰它并不重要——每次访问
IsUpdated
它都会执行查询。就我个人而言,我怀疑这是一个错误,并可能导致攻击性和不可预测的数据查询

许多序列化程序支持序列化回调的概念,这将允许您在序列化结束时执行一些代码;但是,
XmlSerializer
不支持此功能。所以这不是一个选择


不太清楚您想要实现什么,但我只是在某个时候调用一个方法。

我有点困惑。我认为(没有检查)XmlSerializer会忽略一个get only简单值(不是列表)。这是你的真实代码吗?对于get only,您期望发生什么?我期望它执行proc并从DB获取最新的值。我相信您对XmlSerializer的看法是正确的,并且只获取值。上面的代码是我添加XmlIgnoreAttribute的最新代码;我曾经有一个简单的set{}块,为什么会这样呢?反序列化程序对getter不太感兴趣(列表等除外),即使它确实运行了(不应该),因为它不在任何地方存储任何东西。。。你怎么知道?我不认为这是故意的,这只是它的方式。直到我们开始使用这个DLL并注意到这个属性的问题,我们才打开代码并注意到了这一点并修改了代码。当我们进行调试时,DB总是返回一个结果,而不是反序列化对象返回的结果,尽管有SQL调用。所以我发布这个问题是为了尝试了解XmlSerializer的内部工作原理。谢谢Marc的回复。我想要的是更好地理解序列化程序在这种情况下的工作方式。我没有太多地使用它,尤其是像这样,所以我在寻找任何信息来解释我看到的结果(谷歌搜索这个特定问题的搜索量很小:))我认为方法调用可能是对这段代码的一个很好的改变。@BrianG行为很简单:它序列化任何它既能读又能写的公共内容;然后反过来说。它既不序列化也不反序列化您的属性,因为它不是读+写。忽略空白集块(SET {})是差编码和序列化此属性是无用的,有没有一种方法可以让您想到,在反序列化类之后立即访问IsUpdated属性将返回序列化的值,而不是get方法中代码的结果(在我的例子中是SQL proc result)?因为这就是我看到的行为。再次感谢@再说一次,什么序列化值?get only属性不会在
XmlSerializer
下序列化。同样,过去有一个set方法为空(set{}),因此它被序列化。是的,我同意,对于这种类型的属性,方法调用将是一个更好的方案(或者缺少)
<SomeType>
  <Foo>def</Foo>
</SomeType>