Как создать XmlMappingSource во время выполнения? - PullRequest
1 голос
/ 25 февраля 2009

(Follow-Up-Question to Как изменить имя / источник таблицы LINQ O / R-M во время выполнения? )

Мне нужно изменить источник таблицы таблицы 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);

Моя проблема: я не могу найти хорошую документацию по отображению, поэтому извлечение необходимой информации весьма подвержено ошибкам - возможно, кто-то может указать мне хорошие документы по сопоставлению или, что еще лучше, пример кода создать файл сопоставления?

Ответы [ 3 ]

1 голос
/ 26 февраля 2009

Используйте шаблоны с открытым исходным кодом Damien Guard T4. Они делают все, что может сделать SQLMetal, и даже больше, и у вас будет полный движок T4.

1 голос
/ 25 февраля 2009

Рассматривали ли вы использование LINQ to Entities, форматы отображения для LINQ to Entities задокументированы.

0 голосов
/ 03 августа 2012

У меня была такая же проблема, и у меня не было возможности изменить проект, так как это слишком поздно.

Мне нужно обновить имя базы данных в файле сопоставления в моем решении. Это решение работает.

Отображение моей базы данных

<?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;
    }`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...