generate XML from a dynamic dataset - asp.net

I have an ASP.net application in c# where I have a dataset which I can transfer to xml by using the following simple codeblock:
string result;
using (StringWriter sw = new StringWriter())
{
ds.WriteXml(sw);
result = sw.ToString();
}
Which generates an xml block like the following:
<NewDataSet>
<ImageInfo>
<ImageID>1</ImageID>
<ImageName>untitled.bmp</ImageName>
<ImagePath>Some Path</ImagePath>
<Width>800</Width>
<Height>190</Height>
<TileSize>256</TileSize>
<Overlap>1</Overlap>
<MimeType>image/jpeg</MimeType>
<Scale />
</ImageInfo>
</NewDataSet>
This is obviously an example of one row, there are multiple rows in the dataset. Now, I dont know how to format a XML block dynamically.
Can anyone point me to some good tutorials on this?
I want the XML to be formatted like the following
<data>
<Columns>
<Column Name= "ImageID"/>
<Column Name= "ImageName"/>
<Column Name= "ImagePath"/>
<Column Name= "Width"/>
<Column Name= "Height"/>
<Column Name= "TileSize"/>
<Column Name= "Overlap"/>
<Column Name= "MimeType"/>
<Column Name= "Scale"/>
</Columns>
<Rows>
<Row>
<Cell>1</Cell>
<Cell>untitled.bmp</Cell>
<Cell>Some Path</Cell>
<Cell>800</Cell>
<Cell>190</Cell>
<Cell>256</Cell>
<Cell>1</Cell>
<Cell>image/jpeg</Cell>
<Cell></Cell>
</Row>
<Row>
.
.
.
</Row>
</Rows>
</data>
Can anyone guide me how to do this?
In my application, I wont be knowing the structure of the dataset beforehand. i.e. there can be a resulting dataset where I have more columns than the ones described in the example. How should I go about this? Any help would be much appreciated.

Try using a DataTable and then convert that DataTable to an XML stream or a file.
DataTable myDataTable = myDataSet.Tables[0];
myDataTable.WriteXml(..);
You will find whole bunch of overloads like TextWriter, Stream. Finally you need to modify that xml to add the nodes besides that DataTable.

This can be a work around. The code standard can be better but for now you can use the following:
XmlDocument doc = new XmlDocument();
XmlDocument Outputdoc = new XmlDocument();
doc.LoadXml("<NewDataSet> <ImageInfo> <ImageID>1</ImageID> <ImageName>untitled.bmp</ImageName> <ImagePath>Some Path</ImagePath> <Width>800</Width> <Height>190</Height> <TileSize>256</TileSize> <Overlap>1</Overlap> <MimeType>image/jpeg</MimeType> <Scale /> <ImageID>1</ImageID> <ImageName>untitled.bmp</ImageName> <ImagePath>Some Path</ImagePath> <Width>800</Width> <Height>190</Height> <TileSize>256</TileSize> <Overlap>1</Overlap> <MimeType>image/jpeg</MimeType> <Scale /></ImageInfo> </NewDataSet> ");
XmlNode node = doc.SelectSingleNode("/NewDataSet/ImageInfo");
XmlNodeList nodes = node.ChildNodes;
XmlDocument newdoc = null;
StringBuilder sb = new StringBuilder("<data><Columns>");
string lastNode=string.Empty;
string firstNode = string.Empty;
foreach (XmlNode n in node.ChildNodes)
{
if(n.Name.Equals(firstNode))
break;
if (string.IsNullOrEmpty(firstNode))
firstNode = n.Name;
newdoc = new XmlDocument();
XmlNode newNode = newdoc.CreateElement("Column");
XmlAttribute newAttribute = newdoc.CreateAttribute("Name");
newAttribute.Value = n.Name;
newNode.Attributes.Append(newAttribute);
newdoc.AppendChild(newNode);
sb.Append(newdoc.InnerXml);
lastNode=n.Name;
}
sb.Append("</Columns><Rows><Row>");
foreach (XmlNode xnode in node.ChildNodes)
{
XmlDocument newdoc1 = new XmlDocument();
XmlNode newNode = newdoc1.CreateElement("Cell");
newNode.InnerText = xnode.InnerText;
newdoc1.AppendChild(newNode);
sb.Append(newdoc1.InnerXml);
if (xnode.Name.Equals(lastNode))
sb.Append("</Row>");
}
sb.Append("</Rows></data>");
This is a very quick way to accomplish your task. You are free to standarize the code. Now look at the output which looks same as you need:
<data>
<Columns>
<Column Name="ImageID" />
<Column Name="ImageName" />
<Column Name="ImagePath" />
<Column Name="Width" />
<Column Name="Height" />
<Column Name="TileSize" />
<Column Name="Overlap" />
<Column Name="MimeType" />
<Column Name="Scale" />
</Columns>
<Rows>
<Row>
<Cell>1</Cell>
<Cell>untitled.bmp</Cell>
<Cell>SomePath</Cell>
<Cell>800</Cell>
<Cell>190</Cell>
<Cell>256</Cell>
<Cell>1</Cell>
<Cell>image/jpeg</Cell>
<Cell></Cell>
</Row>
<Cell>1</Cell>
<Cell>untitled.bmp</Cell>
<Cell>Some Path</Cell>
<Cell>800</Cell>
<Cell>190</Cell>
<Cell>256</Cell>
<Cell>1</Cell>
<Cell>image/jpeg</Cell>
<Cell></Cell>
</Row>
</Rows>
</data>
Note: I have used the same data collection to make two rows of data.

Related

FastReport open source object data source

I try to use FastReport open source to build reports from data I'll provide to the report.
I've found what I want in the demos (https://github.com/FastReports/FastReport/tree/master/Demos/OpenSource/DataFromBusinessObject/DataFromBusinessObject)
In this demo, I see in the report file that a BusinessObjectDataSourceis used, which seems to be what I want to use.
However, I don't see a way to add this kind of source in the community designer. Do I need to add all of this manually ? Or is there a way to generate the needed markup ? I can't find the solution on their site.
I found a way by making the needed xml by hand like this:
<BusinessObjectDataSource Name="Invoices" ReferenceName="Invoices" Enabled="true">
<Column Name="Reference" DataType="System.String"/>
<Column Name="Date" DataType="System.String"/>
<Column Name="CompanyName" DataType="System.String"/>
<Column Name="InvoiceEmail" DataType="System.String"/>
<Column Name="VAT" DataType="System.String"/>
<Column Name="Street" DataType="System.String"/>
<Column Name="Number" DataType="System.String"/>
<Column Name="City" DataType="System.String"/>
<Column Name="ZipCode" DataType="System.String"/>
<Column Name="Country" DataType="System.String"/>
<Column Name="TotalPrice" DataType="System.Decimal"/>
<Column Name="VATValue" DataType="System.Decimal"/>
<Column Name="VATPercentage" DataType="System.Decimal"/>
<Column Name="VATComment" DataType="System.String"/>
</BusinessObjectDataSource>
The only drawback is that I need to update this if my object changes (but at least is is working !)
I found a way to generate an empty report with the fields generated from a business object.
You only have to create an empty report object, call "RegisterBusinessObject()" on its Dictionary property, and then save the report itself:
var report = new Report();
report.Dictionary.RegisterBusinessObject(
new List<Invoice>(), // a (empty) list of objects
"Invoices", // name of dataset
2, // depth of navigation into properties
true // enable data source
);
report.save(#"invoiceReport.frx");
You still need to update the report description if your object changes, but at least you don't have to code it by hand!

Propel and related data using FOSUserbundle

I'm using FOSUserBundle and I've created a Message table with two columns, that are relating to the User from FOSUserBundle.
I want to get messages and information about the author using one query.
Following schema.xml:
<?xml version="1.0" encoding="UTF-8"?>
<database name="default" namespace="Acme\StoreBundle\Model" defaultIdMethod="native">
<table name="message">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="title" type="varchar" size="64" required="true" defaultValue="(untitled)"/>
<column name="content" type="longvarchar" />
<column name="author_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user">
<reference local="author_id" foreign="id" />
</foreign-key>
<column name="recipient_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user">
<reference local="recipient_id" foreign="id" />
</foreign-key>
</table>
</database>
I was trying many options, with no result.
When I try, what seems to be logical:
$messages = MessageQuery::create()
->join('Message.Authorid')
->findByRecipientId(1);
I get an error: "Unknown table or alias Message"
With:
->join('Authorid')
Error: "Unknown relation Authorid on the Acme\StoreBundle\Model\Message table"
What am I doing wrong?
Thank you for your help.
Ok, I found it out.
The schema for both author and recipient has to look like:
...
<column name="author_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user" phpName="Author">
<reference local="author_id" foreign="id" />
</foreign-key>
<column name="recipient_id" type="integer" required="true" />
<foreign-key foreignTable="fos_user" phpName="Recipient">
<reference local="recipient_id" foreign="id" />
</foreign-key>
...
The important part is the phpName.
Now the controller. And here is something weird that happens, but it doesn't disturb.
$messages = MessageQuery::create()
->find();
return $this->render('AcmeStoreBundle:Message:index.html.twig',
array('messages' => $messages)
);
And after this easy code, I have access to everything from twig.
At this point I'd like to show an example:
When the controller looks like above, then
# AcmeStoreBundle:Message:index.html.twig
messages
Shows every field of the message table like:
Acme\StoreBundle\Model\Message_0: Id: 1 CreatedAt: !!php/object:O:8:"DateTime":3: {s:4:"date";s:19:"2013-03-20 13:00:00";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";} Title: (untitled) Content: 'test content' AuthorId: 1 RecipientId: 2 Acme\StoreBundle\Model\Message_1: Id: 2 CreatedAt: !!php/object:O:8:"DateTime":3:{s:4:"date";s:19:"2013-03-20 13:15:22";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";} Title: (untitled2) Content: 'bla bla content 2' AuthorId: 2 RecipientId: 1
As you can see, there is nothing about the relationship with author or recipient, but when I call message.author.username, or message.recipient.username (in the for loop of messages) I'm getting this. And this is what I actually expected.
And now when the controller looks like:
$messages = MessageQuery::create()
->joinWith('Author')
->find();
return $this->render('AcmeStoreBundle:Message:index.html.twig',
array('messages' => $messages)
);
messages (in twig) throws all the fields like above, and an author object (called author, not user, because of phpName from the schema).
Thank you guys for reading my question and many thx for participation.
The join method takes the relation using tables or phpName aliases, not the fields. So you probably want:
->join("Message.Author")
Or, as your foreign key suggests, maybe this?
->join("Message.FosUser")
UPDATE
With two FK references to the same table, you will want to use the phpName and refPhpName attributes of the foreign-key tag:
<table name="message">
...
<foreign-key foreignTable="fos_user" phpName="Author" refPhpName="AuthoredMessage">
<reference local="author_id" foreign="id" />
</foreign-key>
<foreign-key foreignTable="fos_user" phpName="Recipient" refPhpName="ReceivedMessage">
<reference local="recipient_id" foreign="id" />
</foreign-key>
</table>
Then you could try using ->join('Message.Author') or ->join('Message.Recipient')
See the documentation of the foreign-key element.

How to rename an attribute in XML?

i have XMl like
<record id="1" name="CustomerInfo">
<field name="id" index="1" type="String"/>
</record>
i want to rename "name" attribute to "match" like
<record id="1" match="CustomerInfo">
<field match="id" index="1" type="String"/>
</record>
You can add a new field based on the old one and then delete the old :
var xml:XML = <record id="1" name="CustomerInfo">
<field name="id" index="1" type="String"/>
</record>;
// create new one
xml.field.#match=xml.field.#name;
// delete old one
delete xml.field.#name;
Try setName method: I haven't used it, but the docs says it will work on attributes too.
var xml:XML = <record id="1" name="CustomerInfo">
<field name="id" index="1" type="String"/>
</record>;
xml.#name[0].setName("match");
trace(xml.toXMLString());
xml.field.#name[0].setName("match");
trace(xml.toXMLString());
Update: It works in Firefox e4x javascript, so it should work in ActionScript too. Try this:
var xml:XML = <record id="1" name="CustomerInfo">
<field name="id" index="1" type="String"/>
</record>;
var names:XMLList = xml.descendants("#name");//all `name` attributes
for(var i:Number = 0; i < names.length(); i++)
{
names[i].setName("match");
}
trace(xml.toXMLString());

LINQ TO SQL Mapping Error

Iam using LINQ To SQL with POCO's and XML mapping. I am getting the following error when I try to run the application: Cannot find type 'MyProject.DataTransfer.User' from mapping.
Below is the mapping:
<Table Name="Users" Member="User">
<Type Name= "MyProject.DataTrasnfer.User">
<Column Name="UserID" Member="UserID" DbType="Int NOT NULL IDENTITY" IsDbGenerated="true"
IsPrimaryKey="true"/>
<Column Name="UserName" Member="UserName" DbType="nvarchar(100) NOT NULL" />
<Column Name="Password" Member="Password" DbType="nvarchar(32)"/>
<Column Name="IsActive" Member="IsActive" DbType="bit NOT NULL"/>
<Column Name="InsertedBy" Member="InsertedBy" DbType="Int NOT NULL" />
<Column Name="InsertedDate" Member="InsertedDate" DbType="DateTime NOT NULL" />
<Column Name="UpdatedBy" Member="UpdatedBy" DbType="Int NOT NULL" />
<Column Name="UpdatedDate" Member="UpdatedDate" DbType="DateTime NOT NULL" />
<Column Name="Version" Member="Version" DbType="rowversion NOT NULL" IsDbGenerated="true"
IsVersion="true" AutoSync="Always"/>
</Type>
</Table>
But 'MyProject.DataTransfer.User' exists in the solution. What could be the possible reasons for this error?
Typo: MyProject.DataTrasnfer.User. You have transposed the s and the n.
I suppose that you have a class MyProject.DataTraSNfer.User in mapping and MyProject.DataTraNSfer.User in code. Misprint in post or in code?

LINQ to SQL: inner join with manual association on SQL 2000

I have two tables in a one to many relationship. (products and qty break pricing). At the database level I cannot create a relationship between the two tables. I brought those two tables into LINQ and created the association manually.
I need to do a big LINQ query and have the tables be joined. My problem is it's not using a join to get the data. LINQ is using 1 select on the main table, then 1 select for each row in that main table.
Dim db As New LSSStyleDataContext(connString)
Dim options As New DataLoadOptions()
options.LoadWith(Function(c As commerce_product) c.commerce_qty_breaks)
db.LoadOptions = options
Dim dbProducts = (From prods In db.commerce_products).ToList
Any thoughts on why this might be? Thanks!
Paul
EDIT: here are the two tables:
CREATE TABLE [dbo].[commerce_product](
[pf_id] [int] NOT NULL,
[name] [varchar](500) COLLATE SQL_Latin1_General_CP1_CI_AS
[description] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[restricted] [varchar](5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
CONSTRAINT [PK_commerce_product_1] PRIMARY KEY NONCLUSTERED
(
[pf_id] ASC
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
And the other table:
CREATE TABLE [dbo].[commerce_qty_break](
[pf_id] [int] NOT NULL,
[sku] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[qty] [int] NOT NULL,
[list_price] [int] NOT NULL,
[break_id] [int] NOT NULL,
CONSTRAINT [PK_commerce_qty_break] PRIMARY KEY CLUSTERED
(
[pf_id] ASC,
[qty] ASC,
[break_id] ASC
) ON [PRIMARY]
) ON [PRIMARY]
The DBML is straight forward with only the two tables. I created an association between the two tables, "commerce_product" being the parent and "commerce_qty_break" being the child joined by "PF_ID".
I can write something like this:
Dim dbproducts = From prods In db.commerce_products _
Join qtys In db.commerce_qty_breaks On prods.pf_id Equals qtys.pf_id _
Select prods
And i see that it joins on the table in the query, but as soon as i try and spin through the "qty_breaks" it starts executing selects to get that info.
I'm totally stumped.
Edit 2: Here is the DBML:
<?xml version="1.0" encoding="utf-8"?>
<Database Name="LSScommerceDB_DevB" Class="LSSStyleDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
<Connection Mode="AppSettings" ConnectionString="***" SettingsObjectName="HSLPriceUpdate.My.MySettings" SettingsPropertyName="LSScommerceDB_DevBConnectionString" Provider="System.Data.SqlClient" />
<Table Name="dbo.commerce_product" Member="commerce_products">
<Type Name="commerce_product">
<Column Name="pf_id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
<Column Name="name" Type="System.String" DbType="VarChar(500)" CanBeNull="true" />
<Column Name="description" Type="System.String" DbType="Text" CanBeNull="true" UpdateCheck="Never" />
<Column Name="list_price" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="image_file" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
<Column Name="image_width" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="image_height" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="sale_price" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="sale_start" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="sale_end" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="attr_label1" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
<Column Name="attr_label2" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
<Column Name="attr_label3" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
<Column Name="attr_label4" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
<Column Name="attr_label5" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
<Column Name="sku" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
<Column Name="UOM" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="Sell_Pack" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="mfg_model_number" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="mfg_id" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="logo_file" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
<Column Name="drop_ship" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="lead_time" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="hazard_flag" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
<Column Name="publish_date" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="restricted" Type="System.String" DbType="VarChar(5)" CanBeNull="true" />
<Association Name="commerce_product_commerce_qty_break" Member="commerce_qty_breaks" ThisKey="pf_id" OtherKey="pf_id" Type="commerce_qty_break" />
</Type>
</Table>
<Table Name="dbo.commerce_qty_break" Member="commerce_qty_breaks">
<Type Name="commerce_qty_break">
<Column Name="pf_id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
<Column Name="sku" Type="System.String" DbType="VarChar(100) NOT NULL" CanBeNull="false" />
<Column Name="qty" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
<Column Name="list_price" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="sale_price" Type="System.Int32" DbType="Int" CanBeNull="true" />
<Column Name="sale_start" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
<Column Name="sale_end" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
<Column Name="break_id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
<Association Name="commerce_product_commerce_qty_break" Member="commerce_product" ThisKey="pf_id" OtherKey="pf_id" Type="commerce_product" IsForeignKey="true" />
</Type>
</Table>
</Database>
EDIT 3: Apparently this is only an issue in SQL 2000. SQL 2008 works fine. I have other tables that do eager loading in SQL 2000 and i can't figure out what the difference is between these two tables.
I created a VB console app and created the schema as you have it here.
Also - the relationship is PK -> PK so does this mean it's supposed to be a one-to-one relationship?
I populated the tables with a row each (see below) and ran the code you've listed above. I ran SQL Profiler and it only queried once:
SELECT [t0].[pf_id], [t0].[name], [t0].[description], [t0].[restricted],
[t1].[pf_id] AS [pf_id2], [t1].[sku], [t1].[qty], [t1].[list_price],
[t1].[break_id], (
SELECT COUNT(*)
FROM [dbo].[commerce_qty_break] AS [t2]
WHERE [t2].[pf_id] = [t0].[pf_id]
) AS [value]
FROM [dbo].[commerce_product] AS [t0]
LEFT OUTER JOIN [dbo].[commerce_qty_break] AS [t1] ON [t1].[pf_id] = [t0].[pf_id]
ORDER BY [t0].[pf_id], [t1].[qty], [t1].[break_id]
I wanted to make sure that the Data Options was forcing a deep load, so I added some extra code - here's the full code I used (and only the single query as above was traced):
Dim options As New DataLoadOptions()
options.LoadWith(Function(c As commerce_product) c.commerce_qty_breaks)
db.LoadOptions = options
Dim dbProducts = (From prods In db.commerce_products).ToList
Dim dbProduct = dbProducts.First().commerce_qty_breaks
Dim x = dbProduct.First().list_price
Here's the test data:
INSERT INTO [Test].[dbo].[commerce_product] ([pf_id],[name],[description],[restricted]) VALUES (1,'Test','Test','Test')
GO
INSERT INTO [Test].[dbo].[commerce_qty_break] ([pf_id],[sku],[qty],[list_price],[break_id]) VALUES (1,'22',1,1,1)
GO
hey, not sure i completely understood your question, but here's some info,
By default LINQ to SQL adopts lazy binding, meaning it won't query the database until it needs to. That's why you're getting multiple queries.
There are few things you can do to avoid multiple hits on the DB:
You can turn off lazy binding globally in the LINQ to SQL designer. But then you'll always perform JOINS if your tables have any relationships.
You do the JOIN manually in the LINQ query. If you do this, you'll have to specify which "fields" you want to return in your LINQ query to get back the JOINED data. And if you do this, then you'll be returning an Anonymous type
NOTE: LINQ to SQL doesn't support LEFT JOINS. If you google LINQ to SQL Left Joins you'll see plenty of info on this particular subject
cheers, and good luck!
Go grab LINQPad. It's great for playing with stuff like this.
Did you try something like this?
Dim dbproducts = From prods In db.commerce_products _
Join qtys In db.commerce_qty_breaks On prods.pf_id Equals qtys.pf_id _
Select new {prods, qtys}
I ended up using the entity framework and all is well.

Resources