I am trying to convert a Datatable to a c# class.
I am using the following method to convert
this i developed as a console application. I have not referenced entity framework on console application.
**Class1** items = dt.AsEnumerable().Select(row =>
new Class1
{
id = row.Field<string>("id"),
name = row.Field<string>("name")
}).FirstOrDefault();
when i implied this code to my real time project
I am getting the following error
The type 'System.Data.Objects.DataClasses.IEntityWithKey' is defined in an assembly that is not referenced.
I do not want to refer entity frame work and in my console application i have not referenced any thing.It is working perfectly. why i am getting this error in my real time project
Is there any other way to convert datatable to c# class.
My application is in c# ,visual studio 2008 console application.
error is showing in Class1
Console and real time project are in vs 2008
Once you have your referencing issue sorted out, and assuming you do actually want to convert from rows in a DataTable to instances of a .NET class, take a look at this blog post.
Lets you do this:
// create and fill table
DataTable table = new DataTable();
table.Columns.Add("Id", typeof(int));
table.Rows.Add(new object[]{1});
table.Rows.Add(new object[]{2});
table.Rows.Add(new object[]{3});
// create a wrapper around Rows
LinqList<DataRow> rows = new LinqList<DataRow>(table.Rows);
// do a simple select
IEnumerable<DataRow> selectedRows = from r in rows
where (int)r["Id"] == 2
select r;
// output result
foreach (DataRow row in selectedRows)
Console.WriteLine(row["Id"]);
I just wrote this as a quick test - literally just add new console app and the below code:
static void Main(string[] args)
{
var table = new DataTable();
table.Columns.Add("id", typeof(string));
table.Columns.Add("name", typeof(string));
table.Rows.Add(new object[] { 1, "test" });
var item = table.AsEnumerable().Select(row =>
new {
id = row.Field<string>("id"),
name = row.Field<string>("name")
}).First();
Console.WriteLine(item.name);
}
I'm only referencing System.Data and System.Data.DataSetExtensions (well.. and System/System.Core/Microsoft.CSharp/System.Xml/System.Xml.Linq). The problem isn't with the code you posted, it lies somewhere that we can't see. Can you post the full list of DLLs that you are referencing.
You definitely do not require a reference to System.Data.Entity.dll to do what you're doing. Search through all your source files for System.Data.Objects.DataClasses to see where you are referencing a class in the Entity Framework library. It might also be pulled in from a library you are referencing.
Related
I"m using SSIS package with Script task to get files not older then n days and it's working fine, but now I need to bring into next step CreatedTime for each file. Below I pasted the body of my script. It works partially I just can't pass new var into LastUpdated. Frankly don't know how to deal with this structure, can I add another dimension to into existing list of create another list. I plan to use User:LastUpdated in the same way as FileNameArray.
Tx much !)
DataTable NewList = new DataTable();
DataColumn col = new DataColumn("FileName");
NewList.Columns.Add(col);
DataColumn col2 = new DataColumn("LastUpdated", System.Type.GetType("System.DateTime"));
NewList.Columns.Add(col2);
foreach (string f in MyDirFiles)
{
finf = new System.IO.FileInfo(f);
if (finf.LastWriteTime > DateTime.Now.AddDays(-7) )
)
{
NewList.Rows.Add(System.IO.Path.GetFileName(f) ,
System.IO.File.GetCreationTime(f));
}
}
Dts.Variables["User::FileNameArray"].Value = NewList.Columns["FileName"]; //<--- need convert into object
////**Dts.Variables["User::LastUpdated"].Value = NewList(xxx);
Dts.TaskResult = (int)ScriptResults.Success;
From your code and comments - can conclude the following:
NewList2 variable has DataTable type (not present in code)
User:LastUpdated SSIS package variable has DateTime type
In this case - you are trying to assign a complex structure (DataTable) to single value DateTime variable, which certainly raises an error. To do so, change type of User:LastUpdated to Object.
One can extend NewList table to contain both columns, like in the example below
DataTable NewList = new DataTable();
DataColumn col = new DataColumn("FileName");
NewList.Columns.Add(col);
DataColumn col2 = new DataColumn("LastUpdated", System.Type.GetType("System.DateTime"));
NewList.Columns.Add(col2);
Adding a new row will be more awkward.
DataRow newRow = NewList.NewRow();
newRow["FileName"] = System.IO.Path.GetFileName(f);
newRow["LastUpdated"] = System.IO.File.GetCreationTime(f);
NewList.Rows.Add(newRow);
I have written the code with reference from one of the post on this forum but getting below error
my csv data as
how to proceed?
Before you can add data to a DataTable, you must add the columns you will need. You can also check if the column exists before adding it using dt.Columns.Contains.... If your CSV file has a header row you can use that to give your columns some header text.
Something like (this compiles but not actually run):
var dt = new DataTable();
var rows = csvfile.Split('\n');
// Add the columns
var colHeaders = rows[0].Split(',');
foreach(var header in colHeaders)
{
dt.Columns.Add(header, typeof(string));
}
// now add the data rows
foreach(var row in rows.Skip(1))
{
if(!string.IsNullOrEmpty(row))
{
var data = row.Split(',');
foreach(var d in data)
{
dt.Rows.Add(d);
}
}
}
There are other examples available on the internet specifically for reading CSV files into DataTables (here's one).
Quick question regarding filehelper library:
I have used file helper engine to read stream, do my validation and if the CSV file has not got a header we need to match/map it to my model: i.e
id, name, age, phone, sex,
but the CSV might not come in this format/order all the time and we need to match them using a drop down list for each column.
Is there any way I can do this?
Thannks,
The short answer, no. BUT you can create a dependent class dynamically:
Since you have the list of possible fields in your JSON file, I would recommend doing a basic System.IO ReadLine for the first data row, and then parse by your delimiter for the individual headers. i.e.:
string headerString;
var headers = new List<String>();
var file = new System.IO.StreamReader("C:\\myFile.txt");
headerString = file.ReadLine();
file.Close();
headers = headerString.Split(',').ToList();
now you have the list of strings for the first row to match against your JSON file. Then you can create your dependent class using System.Reflection.Emit (referenced link below)
typeBuilder.SetParent(typeof(MyFileHelperBaseClass));
// can place the property definitions in a for loop against your headers
foreach(string h in headers){
typeBuilder.DefineProperty("<header/col#>", ..., typeof(System.Int32), null);
}
stackoverflow article 14724822: How Can I add properties to a class on runtime in C#?
File Helpers gets a little finicky at times, so it will take some tweaking.
Hope this helps
You can use File.ReadLines(#"C:\myfile.txt").First() to read the first line and get the headers.
Then you can just use a FileHelpers CodeBuilder to build your runtime class. From the example for a delimited csv file:
DelimitedClassBuilder cb = new DelimitedClassBuilder("Customers", ",");
cb.IgnoreFirstLines = 1;
cb.IgnoreEmptyLines = true;
cb.AddField("BirthDate", typeof(DateTime));
cb.LastField.TrimMode = TrimMode.Both;
cb.LastField.FieldNullValue = DateTime.Today;
cb.AddField("Name", typeof(string));
cb.LastField.FieldQuoted = true;
cb.LastField.QuoteChar = '"';
cb.AddField("Age", typeof(int));
engine = new FileHelperEngine(cb.CreateRecordClass());
DataTable dt = engine.ReadFileAsDT("testCustomers.txt");
Then you can traverse the resulting data table.
I have a very large Visual Studio project and am in the process of debugging a complicated Linq query.
The program gets it's data from a stored procedure in SQL, converts it to data tables and then does some background magic on it.
Somehow, all the questions I find here involve how to debug a Linqpad query in visual studio, not the other way round.
Is there a short and easy way to serialize an EnumerableRowCollection in Visual Studio, and then deserialize it in LinqPad so I can play around with it in LinqPad? Or maybe there is another (better) way to debug?
So let's say I have this:
var table = processManager.getDataTable();
var filteredRows = from row in table.AsEnumerable()
where (row.Field<DateTime>("DateFrom") <= currentDate &&
row.Field<DateTime>("DateTo") >= currentDate)
select new
{
....
};
The first line (processManager.getDataTable()) MUST run in visual studio. How can I debug in LinqPad?
Based on your comment, you essentially want to export the datatable from your solution and import it into Linqpad for further processing.
The easiest solution would be to export it into a csv - file. Let's take "vc 74"s solution posted here for the export:
StringBuilder sb = new StringBuilder();
//assuming processManager.getDataTable() returns a DataTable object
IEnumerable<string> columnNames = processManager.getDataTable().Columns.Cast<DataColumn>().
Select(column => column.ColumnName);
sb.AppendLine(string.Join(",", columnNames));
foreach (DataRow row in dt.Rows)
{
IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
sb.AppendLine(string.Join(",", fields));
}
Now that we have a csv file, lets reimport it in Linqpad:
//Where condition is optional; ensures no blank lines are processed
//to prevent index out of bounds error on Split
var csvData = from row in File.ReadLines(#"path/to/csv/file").Where(arg => !string.IsNullOrWhiteSpace(arg) && arg.Length > 0).AsEnumerable()
//Delimiter
let column = row.Split(';')
select new
{
Prop1 = column[0],
Prop2 = column[1],
Prop3 = column[2],
Prop4 = column[3],
Prop5 = column[4]
};
You can also strongly type it, by defining all columns in a row as a seperate class in Linqpad and then call select new myClass { ... }.
Kind regards
There is an extension that once installed and enabled on a solution, export your debugging variables to LINQPad directly. Check it out, it's called LINQBridgeVS:
It basically maps a custom debugger visualizer to all of the public classes and structs of a solution. So when you run your app, the magnifier glass on the data tip is available on almost any type:
Disclaimer: I'm the author of the extension.
I'm new to C# and my current code seems a bit of a hack- how can I keep combining referenced datatables more efficiently (less lines of code), or at least more readable?
(I have no say in the framework, BTW, I'm playing it as it lies ;))
I lose the last datatable once I reference it again
I can't import rows into a datatable that doesn't share the same schema.
This code address both issues, but man, it seems fugly.
DataTable dt_ref = new DataTable();
DataTable dt_final = new DataTable();
bool datatable_is_cloned;
String[] customer_ids = {"cust_a", "cust_b", "cust_c"}
foreach(String id in customer_ids)
{
if(!obj_cust.Select_by_customer_id(id, ref dt_ref, ref error_msg))
{
//do error handling
}
if(!datatable_is_cloned)
{
dt_final = dt_ref.Clone();
datatable_is_cloned = true;
}
foreach(DataRow r in dt_ref.Rows)
dt_final.ImportRow(r);
}
Edited for clarity.
Problem is is every time I loop and hit the database with another customer id, my dt_ref loses all of its previous results and gains merely the new ones (yes, this is expected behavior).
I want to keep a running total of all the results from select method.