Visualizzazione post con etichetta c#. Mostra tutti i post
Visualizzazione post con etichetta c#. Mostra tutti i post

martedì 7 febbraio 2012

Ignore inline DTD in XML file with LINQ to XML

If we want to read an XML file with LINQ to XML that have DTD inline instructions, normally we use this statement

    XDocument doc = XDocument.Load("myXmlFile.xml");

but... we'll receive an exception.

The Load method of the XDocument has several overloads, including one in particular that takes as a parameter an XmlReader object.
Let's see how to use it:

  XmlReaderSettings settings = new XmlReaderSettings();
  settings.DtdProcessing = DtdProcessing.Ignore;
  XmlReader reader = XmlReader.Create("myFile.xml", settings);
  XDocument doc = XDocument.Load(reader,   LoadOptions.PreserveWhitespace);

First, create a XmlReaderSettings object and set its DtdProcessing property to "Ignore". It causes the DOCTYPE element to be ignored.
Then, create a new XmlReader object using the file path name and XmlReader previously created settings.
Now we can open without previous exception out xml file, passing XmlReader object as argument of XDocument Load method.

giovedì 17 novembre 2011

Trace T-SQL statements generated by Entity Framework

If we want to keep track of a query with Entity Framework without use a profiler, we can use the method ToTraceString which is part of the ObjectQuery object. In practice, this method displays the commands sent from our T-SQL query to the database.

First, when using the ToTraceString method we need an open connection to the database, otherwise we will raise an exception.

Its use is very simple. Here an example:
using (MyEntities ctx= new MyEntities()) {
  var strSql = "SELECT VALUE t FROM MyEntities.Employees AS t";
  var myQuery = ctx.CreateQuery(strSql);
 
  ctx.Connection.Open();
 
  Console.WriteLine(myQuery.ToTraceString());
  Console.ReadLine();
}


The output will be something like:
SELECT
[it].[FirstName] AS [FirstName],
[it].[LastName] AS [LastName],
[it].[Age] AS [Age]
FROM [dbo].[Employees] AS [it]

One important thing about ToTraceString method is that it doesn’t execute the query but it's only output the statement to be executed.

mercoledì 22 giugno 2011

C# - read range of dates without considering all holidays

The problem
I need to calculate the elapsed days between a date and the other, regardless of public holidays and national holidays.

The idea
The first thing to do was to remove from the range of dates on Saturdays and Sundays, in order to consider only working days.
For national holidays but I thought I'd use a database table containing a list of dates as smalldatetime fields.
But I did not want every year to update all the dates of the table, only to set the new year. So I decided to set any date on the database with a fixed year 2011 (but I could also use more than one year 'recently).
The only date to be updated every year is the Easter holiday because it is considered a date "variable".

This is the table:
















My solution
Calculating the difference (in days) between the end date and the start and this would eliminate any other festive dates, according to Saturdays and Sundays and holidays are based on. However, if a holiday falls in one of these two days, obviously the date is eliminated once.

This is the C# code:

public static int GetDateDiff(DateTime start, DateTime end) {

TimeSpan dsDiff = end - start;
int diff = dsDiff.Days;

int diff2 = diff;

if (diff <= 0)
return diff;
using (var ctx = new MyEntities()) {
  //run a cycle on any date, from start to finish
  for(int i = 0; i <= diff2; i++) {
   DateTime dtTemp = start.AddDays(i);
       //a cycle on any holiday date
                 foreach (var t in ctx.T_HOLIDAYS) {
   int yearDiff = t.date.Year - dtTemp.Year;  
   TimeSpan ts = t.date - dtTemp.AddYears(yearDiff);
                        if (ts.Days == 0 && t.date.DayOfWeek != DayOfWeek.Saturday && t.date.DayOfWeek != DayOfWeek.Sunday) {
    diff--;
    break;
   }
   else if (dtTemp.DayOfWeek == DayOfWeek.Saturday || dtTemp.DayOfWeek == DayOfWeek.Sunday) {
    diff--;
    break;
   }
  }//end foreach
 }//end for
}

sabato 31 ottobre 2009

Reading file with LINQ.

LINQ, the new extension in the Microsoft Framework 3.5 very often is very powerful. Today I tried to read a big txt file (104 Mbytes, 5 millions rows).


For first, I created a new Console application in C# .NET 3.5. In the main method i wrote this code:

//start time
long start = Environment.TickCount;
var query = from a in File.ReadAllLines(@"C:\reading_test.txt")
select a;
foreach (string s in query)
;

Console.WriteLine("With ReadAllLines: " + (Environment.TickCount - start).ToString() + " ms");


When executed it on my machine, time result was 3313 ms.

The File.ReadAllLines() method sometimes is useful, but not performant. Infact with a line code only we can read all lines of a file. But there's a problem: if your input file is very big, you'll have a huge wast of memory.
In my example, when this application start memory used was about 17Mb, but after the query was 360Mb !!
This means all read lines are holdings in memory.

I solved this problem in this way:

long start = Environment.TickCount;
using (StreamReader sr = new StreamReader(@"C:\reading_test.txt")) {
var query = from x in sr.GetLines()
select x;
foreach (string s in query)
;
}
Console.WriteLine("With Extension Method: " + (Environment.TickCount - start).ToString() + " ms");

This is my code for GetLines() extension method:

static class ExtensionsClass {
public static IEnumerable GetLines(this StreamReader sr) {
String line;

if(sr == null)
throw new ArgumentNullException();

while((line = sr.ReadLine()) != null)
yield return line;
}
}


The query operator is implemented as an extension method for the StreamReader class. It enumerates the lines provided by the StreamReader one by one, but does not load a line in memory before it's actually needed.
The main point is that this technique allows you to work with huge files while maintaining a small memory usage profile.

With first method (File.ReadAllLines) time elapsed was about 3600 ms. With the second (with extensin method) time elapsed was about 1200 (less than half of first).