Linq к SQL с помощью таблицы на решение для класса:
http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/01/linq-to-sql-inheritance.aspx
Другие решения (такие как мой фаворит, LLBLGen) позволяют другие модели. Лично, мне нравится единственное решение для таблицы со столбцом различителя, но это, вероятно, потому что мы часто запрашиваем через иерархию наследования и таким образом рассматриваем его как нормальный запрос, тогда как запросы определенного типа только требуют "где" изменение.
Все сказали и сделанный, я лично чувствую, что отображение OO в таблицы ставит телегу впереди лошади. Были непрерывные заявления, что несоответствие импеданса между OO и отношениями было решено... и было много OO определенные базы данных. Ни один из них не сбросил мощную простоту отношения.
Вместо этого я склонен разрабатывать базу данных с приложением в памяти, отображать те таблицы на объекты и сборку оттуда. Некоторые находят это как потерю OO в процессе проектирования, но в моем уме слой данных не должен говорить достаточно высоко в Ваше приложение для влияния на дизайн систем высшего порядка, просто потому что Вы использовали реляционную модель для устройства хранения данных .
XmlReader / Writer - это потоки с последовательным доступом. Вам нужно будет прочитать на одном конце, обработать поток, как вы хотите, и записать его на другом конце. Преимущество состоит в том, что вам не нужно считывать все это в память и строить DOM, что вы получите с любым подходом на основе XmlDocument.
Этот метод должен помочь вам начать работу:
private static void PostProcess(Stream inStream, Stream outStream)
{
var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " };
using (var reader = XmlReader.Create(inStream))
using (var writer = XmlWriter.Create(outStream, settings)) {
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
writer.WriteStartElement(reader.Prefix, reader.Name, reader.NamespaceURI);
writer.WriteAttributes(reader, true);
//
// check if this is the node you want, inject attributes here.
//
if (reader.IsEmptyElement) {
writer.WriteEndElement();
}
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.SignificantWhitespace:
writer.WriteWhitespace(reader.Value);
break;
}
}
}
}
Это не так чисто, как создание собственного XmlWriter, но я считаю, что это намного проще.
[EDIT]
Пример того, как вы открываете два потока одновременно, может выглядеть примерно так:
using (FileStream readStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write)) {
using (FileStream writeStream = new FileStream(@"c:\myFile.xml", FileMode.OpenOrCreate, FileAccess.Write)) {
PostProcess(readStream, writeStream);
}
}
I fixed it using the following duct tape coding
public XmlReader FixUpReader(XmlReader reader)
{
reader.MoveToContent();
string xml = reader.ReadOuterXml();
string dslVersion = GetDSLVersion();
string Id = GetID();
string processedValue = string.Format("<ExampleElement dslVersion=\"{1}\" Id=\"{2}\" ", dslVersion, Id);
xml = xml.Replace("<ExampleElement ", processedValue);
MemoryStream ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(xml));
XmlReaderSettings settings = new XmlReaderSettings();
XmlReader myReader = XmlReader.Create(ms);
myReader.MoveToContent();
return myReader;
}
I feel dirty for doing it this way but it is working....
Вы не сможете легко сделать это с помощью XmlReader
- по крайней мере, не без чтения всего XML-документа от читателя, поработать с ним и затем создать новый XmlReader
из результата. Однако это лишает многих смысла использования XmlReader
, а именно возможности потоковой передачи больших документов.
Вы можете потенциально унаследовать от XmlReader
, перенаправляя большую часть вызовы методов к существующему считывателю, но перехватывая их там, где это необходимо, чтобы добавить дополнительные атрибуты и т. д. ... но я подозреваю, что код будет действительно довольно сложным и хрупким.
Я бы предпочел загрузить xml в объект XmlDocument
, использовать коллекцию Attributes
для изменения значения и вызвать метод Save
для обновления этого значения. Приведенный ниже код работает для меня.
public static void WriteElementValue ( string sName, string element, string value)
{
try
{
var node = String.Format("//elements/element[@name='{0}']", sName);
var doc = new XmlDocument { PreserveWhitespace = true };
doc.Load(configurationFileName);
var nodeObject = doc.SelectSingleNode(node);
if (nodeObject == null)
throw new XmlException(String.Format("{0} path does not found any matching
node", node));
var elementObject = nodeObject[element];
if (elementObject != null)
{
elementObject.Attributes["value"].Value = value;
}
doc.Save(configurationFileName);
}
catch (Exception ex)
{
throw new ExitLevelException(ex, false);
}
}
Я также заметил, что при использовании XmlWriter или XmlSerializer пробельные символы сохраняются неправильно, иногда это может раздражать
. string newvalue = "10";
string presentvalue = "";
string newstr = "";
XmlReader xmlr = XmlReader.Create(new StringReader(str));
while (xmlr.Read())
{
if (xmlr.NodeType == XmlNodeType.Element)
{
if (xmlr.Name == "priority")
{
presentvalue = xmlr.ReadElementContentAsString();
newstr = str.Replace(presentvalue, newvalue);
}
}
}
// newstr можно записать обратно в файл ... это отредактированный xml