【问题标题】:how to serialize large class into multiple files如何将大类序列化为多个文件
【发布时间】:2017-12-30 22:45:12
【问题描述】:

我正在尝试自动设置 datagrip 以供工作。每个项目都有一些文件来定义数据源是什么,工作空间是什么样的等等。让我对如何实施感到困惑的部分是“multifile-model”的想法。这是一个示例:为了便于使用,我将每个项目都放在了一个 git 存储库中,并创建了一个新项目并提交了该项目。然后,我向需要 Windows 身份验证的 ms.sql 数据库添加了一个新的数据库连接。在dataSources.xml 中看起来类似于

<project version="4">
  <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
    <data-source name="test" source="LOCAL" uuid="fcc0408c-408c-fcc0-e254-83c7094db613">
      <driver-ref>sqlserver.ms</driver-ref>
      <synchronize>true</synchronize>
      <jdbc-driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</jdbc-driver>
      <jdbc-url>jdbc:sqlserver://myserver\someinstance;databaseName=somedatbase;</jdbc-url>
      <auto-commit>false</auto-commit>
    </data-source>
<!-- 95 more datasources -->
  </component>
</project>

制作该部分相当容易

DataSourceElement.cs

[XmlRoot("data-source")]
public class DataSourceElement
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlAttribute("source")]
    public string Source { get; set; }

    [XmlAttribute("uuid")]
    public Guid Uuid { get; set; }

    [XmlElement("driver-ref")]
    public string DriverRef { get; set; }

    [XmlElement("synchronize")]
    public bool Synchronized { get; set; }

    [XmlElement("jdbc-driver")]
    public string DriverName { get; set; }

    [XmlElement("jdbc-url")]
    public string DriverUrl { get; set; }

    [XmlElement("default-dialect")]
    public string DefaultDialect { get; set; }

    [XmlElement("auto-commit")]
    public bool IsAutoCommit { get; set; }

    [XmlArray("driver-properties")]
    [XmlArrayItem("property")]
    public List<DatagripPropertyElement> DriverProperties { get; set; } = new List<DatagripPropertyElement>();

    [XmlArray("jdbc-additional-properties")]
    [XmlArrayItem("property")]
    public List<DatagripPropertyElement> DriverAdditionalProperties { get; set; } = new List<DatagripPropertyElement>();
}

DataSourceManagerImpl.cs **

[XmlRoot("component")]
public class DataSourceManagerImpl : ComponentElement
{
    [XmlAttribute("format")]
    public string Format { get; set; }

    [XmlAttribute("multifile-model")]
    public bool MultiFileModel { get; set; }

    [XmlElement("data-source")]
    public List<DataSourceElement> DataSources { get; set; } = new List<DataSourceElement>();
}
[XmlRoot("component")]
public abstract class ComponentElement
{
    [XmlAttribute("name")]
    public string Name { get; set; }
}

DataSourceProject.cs

[XmlRoot("project")]
public class DataSourceProject : ProjectElement
{
    [XmlElement("component")]
    public DataSourceManagerImpl Component { get; set; }
}
[XmlRoot("project")]
public abstract class ProjectElement
{
    [XmlAttribute("version")]
    public int Version { get; set; }
}

linqpad 测试

private const string DATAGRIP_PROJECT = @"C:\Users\snyder\.DataGrip2017.3\config\projects";
void Main()
{
    DataSourceManager = new DataSoureProject();
    //initialize omitted
    Save(DATAGRIP_PROJECT, "default");
}

    public void Save(string datagripProjectPath, string datagripProjectName)
    {
        var projectPath = Path.Combine(datagripProjectPath, datagripProjectName, ".idea");
        WriteToFile(DataSourceManager, Path.Combine(projectPath, "datasources.xml"));
    }

    private static void WriteToFile<T>(T obj, string fullPath, bool omitXmlDeclaration = true)
    {
        var settings = new XmlWriterSettings
        {
            OmitXmlDeclaration = omitXmlDeclaration,
            Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
            Indent = true,
        };
        using (var writer = XmlWriter.Create(fullPath, settings))
        {
            var ns = new XmlSerializerNamespaces();
            ns.Add("", "");
            var serializer = new XmlSerializer(typeof(T));
            serializer.Serialize(writer, obj, ns);
        }
    }

然后我查看 datasources.Local.xml,其中包含我想要的位

<data-source name="test" uuid="fcc0408c-408c-fcc0-e254-83c7094db613">
  <database-info product="" version="" jdbc-version="" driver-name="" driver-version="" />
  <domain-auth>true</domain-auth>
</data-source>

起初我想将所述属性添加到我的 DataSourceElement 类中,但不知道如何拆分属性。所以我当时想..好吧,我想我可以复制类并假装它们不同。任何人,搜索都没有出现。所以现在我问.. 是否可以向我的 DataSourceElement 类添加一些属性,这些属性只会添加到另一个文件中?如果有怎么办?

【问题讨论】:

  • 我不明白你需要什么。哪些其他属性需要放在哪个不同的文件中?你的意思是你的 DataSourceElement 有不同的属性吗?像带有子类的基类?还有什么?
  • 利用AutoMapper 将此类映射为更小的定义,让您的生活更轻松。此时,您可以将较小的类序列化为所需的有效负载。
  • 不要使用序列化。您可以使用 XmlDocument 或 XDocument 或 XmlWriter 生成自定义 xml 输出文件。
  • 您可以使用ShouldSerialize pattern 来有条件地抑制基于某些属性的序列化,例如,某个线程静态变量,然后使用线程静态的不同值进行多次序列化。但是@code4life 建议使用DTOsautomapper 听起来更干净。
  • @code4life 我喜欢这个主意。你介意做一个超级简单的例子作为答案吗?

标签: c# serialization xml-serialization datagrip


【解决方案1】:

我想我想到了一些可能只是让它变得更容易的东西,并且基于 @jdweng 和 @code4life cmets

我在想,如果我要检查 jetbrains 项目是否不存在,我可以使用序列化来创建文件夹和文件。这将很容易且非常简单,因为它只是骨架。然后我可以使用XDocument 加载骨架并根据需要使用AutoMapper 更新/创建连接,以便根据需要创建XElements。这应该让生活在各个方面都变得更轻松,并且在需要时可以轻松添加或在 jetbrains 决定更改编码时进行更改。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-01
    • 2021-05-03
    • 2020-11-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多