using System;
using System.Windows.Forms;
using System.IO;
class MainClass
{
public static void SaveMemoryStream(MemoryStream ms, string FileName)
{
FileStream outStream = File.OpenWrite(FileName);
ms.WriteTo(outStream);
outStream.Flush();
outStream.Close();
}
public static void Main()
{
FileStream inStream = File.OpenRead("c:\\text.txt");
MemoryStream storeStream = new MemoryStream();
storeStream.SetLength(inStream.Length);
inStream.Read(storeStream.GetBuffer(), 0, (int)inStream.Length);
storeStream.Flush();
inStream.Close();
SaveMemoryStream(storeStream, "C:\\text.txt" + ".bak");
storeStream.Close();
}
}Tuesday, May 24, 2011
Save FileStream into MemoryStream
XML Serialization
I'm going to demonstrate how to serialize your own objects to and from an XML file.
Since .NET can use reflection to get property names, basic serialization is unbelievably simple.
It only gets slightly difficult when you want to name your XML tags differently than your property
names (but still not very hard). If you've ever used an XML serialization package in C++ like boost,
tinyXML, or libXML2, you'll see how comparatively easy C# is to use.
Let's start with a basic example. Below is an object that stores some information about a Album.
public class Album
{
public string Title
{ get; set; }
public int Rating
{ get; set; }
public DateTime ReleaseDate
{ get; set; }
}
All right, now that we have an object, let's write a function that will save it to XML.
static public void SerializeToXML(Album Album)
{
XmlSerializer serializer = new XmlSerializer(typeof(Album));
TextWriter textWriter = new StreamWriter(@"C:\Album.xml");
serializer.Serialize(textWriter, Album);
textWriter.Close();
}
The first thing I do is create an XMLSerializer (located in the System.Xml.Serialization namespace)
that will serialize objects of type Album. The XMLSerializer will serialize objects to a stream, so we'll
have to create one of those next. In this case, I want to serialize it to a file, so I create a TextWriter.
I then simply call Serialize on the XMLSerializer passing in the stream (textWriter) and the object
(Album). Lastly I close the TextWriter because you should always close opened files. That's it! Let's
create a Album object and see how this is used.
static void Main(string[] args)
{
Album Album = new Album();
Album.Title = "Starship Troopers";
Album.ReleaseDate = DateTime.Parse("11/7/1997");
Album.Rating = 6.9f;
SerializeToXML(Album);
}
static public void SerializeToXML(Album Album)
{
XmlSerializer serializer = new XmlSerializer(typeof(Album));
TextWriter textWriter = new StreamWriter(@"C:\Album.xml");
serializer.Serialize(textWriter, Album);
textWriter.Close();
}
After this code executes, we'll have an XML file with the contents of our Album object.
<?xml version="1.0" encoding="utf-8"?>
<Album xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Title>Starship Troopers</Title>
<Rating>6.9</Rating>
<ReleaseDate>1997-11-07T00:00:00</ReleaseDate>
</Album>
If you noticed, all of the XML tag names are the same as the property names. If we want to
change those, we can simply add an attribute above each property that sets the tag name.
public class Album
{
[XmlElement("AlbumName")]
public string Title
{ get; set; }
[XmlElement("AlbumRating")]
public float Rating
{ get; set; }
[XmlElement("AlbumReleaseDate")]
public DateTime ReleaseDate
{ get; set; }
}
Now when the same code is executed again, we get our custom tag names.
<?xml version="1.0" encoding="utf-8"?>
<Album xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AlbumName>Starship Troopers</AlbumName>
<AlbumRating>6.9</AlbumRating>
<AlbumReleaseDate>1997-11-07T00:00:00</AlbumReleaseDate>
</Album>
Sometimes, in XML, you want information stored as an attribute of another tag instead of a tag
by itself. This can be easily accomplished with another property attribute.
public class Album
{
[XmlAttribute("AlbumName")]
public string Title
{ get; set; }
[XmlElement("AlbumRating")]
public float Rating
{ get; set; }
[XmlElement("AlbumReleaseDate")]
public DateTime ReleaseDate
{ get; set; }
}
With this code, AlbumName will now be an attribute on the Album tag.
<?xml version="1.0" encoding="utf-8"?>
<Album xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
AlbumName="Starship Troopers">
<AlbumRating>6.9</AlbumRating>
<AlbumReleaseDate>1997-11-07T00:00:00</AlbumReleaseDate>
</Album>
Let's move on to something a little more interesting. Let's create another Album and serialize a
List of them to our XML file. Here's the modified code to do just that:
static void Main(string[] args)
{
Album Album = new Album();
Album.Title = "Starship Troopers";
Album.ReleaseDate = DateTime.Parse("11/7/1997");
Album.Rating = 6.9f;
Album Album2 = new Album();
Album2.Title = "Ace Ventura: When Nature Calls";
Album2.ReleaseDate = DateTime.Parse("11/10/1995");
Album2.Rating = 5.4f;
List<Album> Albums = new List<Album>() { Album, Album2 };
SerializeToXML(Albums);
}
static public void SerializeToXML(List<Album> Albums)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Album>));
TextWriter textWriter = new StreamWriter(@"C:\Album.xml");
serializer.Serialize(textWriter, Albums);
textWriter.Close();
}
Now we have XML that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfAlbum xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Album AlbumName="Starship Troopers">
<AlbumRating>6.9</AlbumRating>
<AlbumReleaseDate>1997-11-07T00:00:00</AlbumReleaseDate>
</Album>
<Album AlbumName="Ace Ventura: When Nature Calls">
<AlbumRating>5.4</AlbumRating>
<AlbumReleaseDate>1995-11-10T00:00:00</AlbumReleaseDate>
</Album>
</ArrayOfAlbum>
Ok, so you can see how easy it is to get your objects into an XML document. Let's now look at
how to read an XML document back into our objects - deserialization. The process of deserializing
is very similar to what we did for serialization.
static List<Album> DeserializeFromXML()
{
XmlSerializer deserializer = new XmlSerializer(typeof(List<Album>));
TextReader textReader = new StreamReader(@"C:\Album.xml");
List<Album> Albums;
Albums = (List<Album>)deserializer.Deserialize(textReader);
textReader.Close();
return Albums;
}
Just like before, we first create an XmlSerializer that can deserialize objects of type List<Album>.
The XmlSerializer also deserializes from a stream, so we create a file stream from our XML file.
We then simply call Deserialize on the stream and cast the output to our desired type. Now the
Albums List is populated with objects that we previously serialized to the XML file.
The deserializer is very good at handling missing pieces of information in your XML file. Let's say
the second Album didn't have the AlbumName attribute on the Album tag. When the XML file is
deserialized, it simply populates that field with null. If AlbumRating wasn't there, you'd receive 0.
Since a DateTime object can't be null, if AlbumReleaseDate was missing, you'd receive
DateTime.MinValue (1/1/0001 12:00:00AM).
If the XML document contains invalid syntax, like say the first opening Album tag was missing,
the Deserialize call will fail with an InvalidOperationException. It will also be kind enough to
specify the location in the file where it encountered the error (line number, column number).
One thing to remember is that the basic XML serialization won't maintain references. Let's say
I populated my Albums list with the same Album reference multiple times:
Album Album = new Album();
Album.Title = "Starship Troopers";
Album.ReleaseDate = DateTime.Parse("11/7/1997");
Album.Rating = 6.9f;
List<Album> Albums = new List<Album>() { Album, Album };
Now I have a list containing two of the exact same Album reference. When I serialize and
deserialize this list, it will be converted to two separate instances of the Album object - they
would just have the same information. Along this same line, the XMLSerializer also doesn't
support circular references. If you need this kind of flexibility, you should consider binary serialization.
There's still a lot to cover when it comes to XML serialization, but I think this tutorial covers enough of
the basics to get things rolling. If you've got questions or anything else to say, leave us a comment.
"UPSERT" (UPDATE where exists, INSERT otherwise)
The UPSERT command inserts rows that don't exist and updates the rows that do exist. The Word
UPSERT is a fusion of the words UPDATE and INSERT. UPSERT was officially introduced in the
SQL:2003 standard.
IF FOUND THEN UPDATE ELSE INSERT;
In SQL Server 2008, Microsoft introduces the UPSERT functionality through the MERGE command.
Until now, this UPSERT functionality could only be made available in SQL Server through stored
procedures and cursors, etc.
This article illustrates how to take advantage of the UPSERT functionality via the MERGE command.or
UPDATE ...
FROM ...
WHERE <condition>
-- race condition risk here
IF @@ROWCOUNT = 0
INSERT ...
IF (SELECT COUNT(*) FROM ... WHERE <condition>) = 0
-- race condition risk here
INSERT ...
ELSE
UPDATE ...
where < condition > will be an evaluation of natural keys. None of the above approaches seem to deal well
with concurrency. If I cannot have two rows with the same natural key, it seems like all of the above risk
inserting rows with the same natural keys in race condition scenarios.
Example:
SELECT * FROM Table_1, Table_2
--check first if the record already exists
IF EXISTS(SELECT * FROM Table_1 WHERE Table_1.ReqNr = Table_2.ReqNr)
--if it does, replace it
BEGIN
UPDATE Table_1 SET Table_1.Description = Table_2.Description
{WHERE Table_1.ReqNr = Table_2.ReqNr}
END
--if there is no such record yet, append new rows
ELSE
BEGIN
INSERT INTO Table_1(ReqNr, Description, FD)
SELECT ReqNr, Description, FD FROM Table_2
{WHERE ReqNr NOT IN(SELECT ReqNr FROM Table_2)}
END;
Friday, May 13, 2011
Reverse a String in C#
private
void gridView1_CustomUnboundColumnData(object sender,DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e)
{
GridView view = sender as GridView;
if (e.Column.FieldName == "Reversed" && e.IsGetData)
{
char [] charArray=((InDirectContacts)view.GetRow(e.RowHandle)).Name.ToCharArray();
Array.Reverse(charArray);
string reversedContactName = new string(charArray);
e.Value = reversedContactName;
}
}
Tuesday, May 10, 2011
Selecting Row from XtraGrid with Object type DataBinding.
private
void gridView1_FocusedRowChanged(object sender, |DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
GridView view = sender as GridView;
if (view.SelectedRowsCount > 0) // i there a selected Row?
{
Contacts indirectContact = (Contacts)view.GetRow(e.FocusedRowHandle);
currentSelectedContactId = Convert.ToString(Contact.ContactID);
}
Friday, May 6, 2011
How to make XtraGrid GridControl Columns ReadOnly
1. The first solution is to set the Editable option of the GridView.OptionsBehavior property
to False. In this case, the whole grid becomes read-only.
Select GridControl and click on the arrow on right-top select Run Designer. In the Properties
List go to Options->OptionsBehaviour->Editable= False.. set this property to false.
2. Another solution is to cahnge the ReadOnly or AllowEdit option of your columns.
3. The last solution is to use the ShowingEditor event of the view and disable cell editing via
code using the event handler's e.Cancel parameter.
The OptionsColumn property is part of the GridColumn class.
Open the designer for a GridControl, select a GridView, then click on the Columns icon in the Main section of the NavBar shown at
the left of the designer. This is where you manage your GridColumn objects for the selected GridView. Near the bottom of the
property list on the right side of the designer will be shown the options for a selected column.
Programmatically, you may do the following to make all columns read-only (C#):
foreach( GridColumn gridColumn in gridView1.Columns )
gridColumn.OptionsColumn.ReadOnly = true;
Thursday, May 5, 2011
BindingList save to database
/// Saves the customer properties back to the database.
/// </summary>
public override Boolean SaveItem()
{
Boolean success = false;
// If the entity state is added, need to get the CustomerId back.
bool isOutput = EntityState == EntityStateType.Added ? true : false;
// Pass the properties back to the DAC
// This would not be needed if the base class had code to use Reflection to build
// the parameters from the object properties.
int retVal = Dac.ExecuteNonQuery("CustomerSave_sp",
Dac.Parameter(cnCustomerID, CustomerId, isOutput),
Dac.Parameter(cnLastName, LastName),
Dac.Parameter(cnFirstName, FirstName),
Dac.Parameter(cnAddress, Address),
Dac.Parameter(cnCity, City),
Dac.Parameter(cnState, State),
Dac.Parameter(cnZip, Zip),
Dac.Parameter(cnPhone, Phone),
Dac.Parameter(cnLastUpdateUser, System.Environment.UserName),
Dac.Parameter(cnRowState, EntityState.ToString()));
// If it was an add, update the product ID
if (EntityState == EntityStateType.Added)
CustomerId = retVal;
// Reset the entity's state
this.SetEntityState(EntityStateType.Unchanged);
// Assume success
success = true;
return success;
}
/// <summary> /// Executes a stored procedure that does not return a dataTable
/// and returns the /// first output parameter. /// </summary> /// <param name="storedProcedureName">Name of the stored procedure
/// to execute</param> /// <param name="arrParam">Parameters required by the stored
/// procedure</param> /// <returns>First output parameter</returns> public static int ExecuteNonQuery(string storedProcedureName, params SqlParameter[] arrParam) { int retVal=0; SqlParameter firstOutputParameter = null; DataTable dt = new DataTable(); // Open the connection using (SqlConnection cnn = new SqlConnection(Properties.SettingsDefault.PTConnectionString)) { cnn.Open(); // Define the command using (SqlCommand cmd= new SqlCommand() ) { cmd.Connection = cnn; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = storedProcedureName; // Handle the parameters if (arrParam != null) { foreach (SqlParameter param in arrParam) { cmd.Parameters.Add(param); if (firstOutputParameter == null && param.Direction==ParameterDirection.Output && param.SqlDbType == SqlDbType.Int) { firstOutputParameter = param; } } } // Execute the stored procedure cmd.ExecuteNonQuery(); // Return the first output parameter value if (firstOutputParameter != null) retVal = (int)firstOutputParameter.Value; } } return retVal; }