【问题标题】:How to create an XmlMappingSource during runtime?如何在运行时创建 XmlMappingSource?
【发布时间】:2009-02-25 10:38:26
【问题描述】:

(对How to change LINQ O/R-M table name/source during runtime?的后续问题)

我需要在运行时更改 LINQ 2 SQL O/R-Mapper 表的表源。为此,我需要创建一个XmlMappingSource。在命令行上,我可以使用 SqlMetal 创建此映射文件,但我想在运行时在内存中创建映射文件。 XmlMappingSource 是一个简单的 xml 文件,看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<Database Name="MyDatabase" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
  <Table Name="dbo.MyFirstTable" Member="MyFirstTable">
    <Type Name="MyFirstTable">
      <Column Name="ID" Member="ID" Storage="_ID" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" AutoSync="OnInsert" />
      <Association Name="WaStaArtArtikel_WaVerPreisanfragen" Member="WaStaArtArtikel" Storage="_WaStaArtArtikel" ThisKey="ArtikelID" OtherKey="ID" IsForeignKey="true" />
    </Type>
  </Table>
  <Table Name="dbo.MySecondTable" Member="MySecondTable">
    <Type Name="MySecondTable">
      <Column Name="ID" Member="ID" Storage="_ID" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" AutoSync="OnInsert" />
      <Column Name="FirstTableID" Member="FirstTableID" Storage="_FirstTableID" DbType="UniqueIdentifier NOT NULL" />
      <Association Name="MySecondTable_MyFirstTable" Member="MyFirstTable" Storage="_MyFirstTable" ThisKey="FirstTableID" OtherKey="ID" IsForeignKey="true" />
    </Type>
  </Table>
</Database>

这应该可以使用反射来创建,例如我可以从这样的数据上下文中获取数据库名称:

using System.Data.Linq.Mapping;
using System.Xml.Linq;

XDocument mapWriter = new XDocument();
DatabaseAttribute[] catx = (DatabaseAttribute[])typeof(WcfInterface.WaDataClassesDataContext).GetCustomAttributes(typeof(DatabaseAttribute), false);
XElement xDatabase = new XElement("Database");
xDatabase.Add(new XAttribute("Name", catx[0].Name));
mapWriter.Add(xDatabase);

我的问题:我找不到良好的映射文档,因此提取必要的信息很容易出错 - 也许有人可以向我指出良好的映射文档,或者更好的代码示例创建映射文件?

【问题讨论】:

  • 建议您在开始时明确地说 LINQ to SQL 以避免与 LINQ to Entities 混淆(与 LINQ to SQL 相比,它更像是一种 ORM —— 更丰富的映射能力)。

标签: c# .net xml linq-to-sql


【解决方案1】:

您是否考虑过使用 LINQ to Entities,LINQ to Entities 的映射格式已记录在案。

【讨论】:

  • 实际上,我并没有真正意识到 L2E 可以替代 L2S。那么,在 L2E 中,是否可以只在运行时更改映射?
  • 我不会将 L2E 视为 /replacement/,而是视为“老大哥”。 L2S 简单,但有限; L2E 功能更强大,但更难使用。
  • 那么,L2E中的表名怎么改呢?
  • 我知道你/can/交换映射,只是不/how/。好吧,直到我有时间真正深入研究 L2E。
【解决方案2】:

使用 Damien Guard 的开源 T4 模板。它们可以做 SQLMetal 可以做的所有事情,甚至更多,您将拥有完整的 T4 引擎。

【讨论】:

  • 嗯,也许你能解释一下这对我的问题有什么帮助?
【解决方案3】:

我也遇到了同样的问题,我也没有办法改变项目,因为太晚了。

我需要在我的解决方案中更新映射文件中的数据库名称。 此解决方案有效。

我的数据库映射

<?xml version="1.0" encoding="utf-8"?>
<Database Name="DatabaseName" xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007">
  <Table Name="dbo.tblDictionary" Member="TblDictionary">
    <Type Name="TblDictionary">
      <Column Name="lngRecordID" Member="LngRecordID" Storage="_LngRecordID" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" AutoSync="OnInsert" />
      <Column Name="txtWord" Member="TxtWord" Storage="_TxtWord" DbType="VarChar(50) NOT NULL" CanBeNull="false" />
    </Type>
  </Table>
</Database>

最后是代码:

class Program
    {
        static void Main(string[] args)
        {

        // to get embeded file name you have to add namespace of the application
        const string embeddedFilename = "ConsoleApplication3.FrostOrangeMappings.xml";
        // load file into stream
        var embeddedStream = GetEmbeddedFile(embeddedFilename);
        // process stream
        ProcessStreamToXmlMappingSource(embeddedStream);
        Console.ReadKey();


    }

    private static void ProcessStreamToXmlMappingSource(Stream stream)
    {

        const string newDatabaseName = "pavsDatabaseName";      

        var mappingFile = new XmlDocument();
        mappingFile.Load(stream);
        stream.Close();


        // populate collection of attribues
        XmlAttributeCollection collection = mappingFile.DocumentElement.Attributes;

        var attribute = collection["Name"];
        if(attribute==null)
        {
            throw new Exception("Failed to find Name attribute in xml definition");
        }

        // set new database name definition
        collection["Name"].Value = newDatabaseName;

        //display xml to  user
        var stringWriter = new StringWriter();
          using (var xmlTextWriter = XmlWriter.Create(stringWriter))
          {
              mappingFile.WriteTo(xmlTextWriter);
              xmlTextWriter.Flush();
              stringWriter.GetStringBuilder();
          }
        Console.WriteLine(stringWriter.ToString());

    }
    /// <summary>
    /// Loads file into stream
    /// </summary>
    /// <param name="fileName"></param>
    /// <returns></returns>
    private static Stream GetEmbeddedFile(string fileName)
    {
        var assembly = Assembly.GetExecutingAssembly();
        var stream = assembly.GetManifestResourceStream(fileName);

        if (stream == null)
            throw new Exception("Could not locate embedded resource '" + fileName + "' in assembly");

        return stream;
    }`

【讨论】:

    猜你喜欢
    • 2020-09-12
    • 2021-09-03
    • 2014-08-13
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多