【发布时间】: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 建议使用DTOs 和automapper 听起来更干净。
-
@code4life 我喜欢这个主意。你介意做一个超级简单的例子作为答案吗?
标签: c# serialization xml-serialization datagrip