Weeks ago I created a few (RDLC) reports. To create a Dataset I defined a dummy class and I imported with the procedure, it worked well.
public class DataSetCartaIntestata
{
public string Desc
public string Immage;
public string Name;
}
I did that to get the result of a query with Anonymous type:
public IEnumerable list;
list= b.Results.Where(x=>x.Name="Jack").Select(x=>new{x.Name,x.Image,x.Desc}).ToList();
Now it seems that if I'm going to do that again the procedure won't let me add a Dataset.
When I select new Dataset it creates the Datasource but not the Dataset.
Is there anything I got wrong?
i Found the answare is here the import pocedure import only properties not simple fields of a class even if they are public. so i had to define them.
anyway if I define by hand the Dataset in the RDLC i can access directly fields.
It's easier to make Mistake changing xml plus VS2012 is a bit touchy on the RDLC and crash a lot
Related
I created a DataSet using the "Add" button on the solution explorer on Visual Studio to use the DataSet Desginer, then add my tables (The connection was already done) and created some queries (everything done from the designer) to get specific data, but how can I use those methods from my code?
I tried a lot of ways but I found nothing:
DBDataSet dBDataSet = new DBDataSet();
dBDataSet. //My methods aren't here
dBDataSet.c_Town. //My methods aren't here neither
dBDataSet.c_Town.DataSet. //...
dBDataSet.c_Town.Rows. //...
dBDataSet.c_Town.Columns. //...
So how can I use those methods? I can't find them anywhere
Nevermind...
I was calling the entire class but what I had to call was the TableAdapter of the respective table, then I can use those methods:
c_TownTableAdapter townTableAdapter = new c_TownTableAdapter();
townTableAdapter.GetNameBy("Town");
My bad, but anyways thanks
I have a object, better, a class. It is like a win form, with the parts:
class.cs, class.Designer.cs and the last class.Resx
It is an XtraReport, so what I'm doing is to get this object and serialize it into a xml file that holds enough information about its controls. The xml generated is used on another project, that uses just the xml. The problem is that it is not enough, despite the xml having all information, it still needs the origin object to resolve the controls properly. Basically:
Saving the Xml - First Solution(C# solution):
var originalReport = new MyCompleteReportDrawInDesignerMode();
original.SaveLayoutToXml(#"c:\FileToBeSerializedAndUsedInAnotherProject");
Consuming the Xml - Another solution(C# Solution)
var genericClass = new GenericClass();
genericClass.LoadLayoutFromXml(#"C:\FileGeneratedByDeserializedXML");
Both classes are child from XtraReports:
public class MyCompleteReportDrawInDesignerMode : XtraReport
public class GenericClass : XtraReport
this doest not work, since the Another Solution does not have a clue about MyCompleteReportDrawInDesignerMode. So i thought, why not teletransport the whole object and make it happen
//Build the object
var generator = GetObjectFromText(text);
//Resolve the dependecy check
var objectGenerated = generator.ResolveAssembly();
But I have no clue how to do it or if it is viable. Any thoughts ?
Update:
I wanna store the class implementation in the database and rebuild it from another application, since the xml transformation is causing information loss.
Let me introduce a little more deeper context. We are building a reporting server application. The process is basically:
1 - Desginer the XtraReport in designer mode, set the fields databindings, set the xrsubreports reportsource if any
2 - Make a xml file from it and save in local C:\ hard driver.
3 - In another application, the user uploads this file and serialize it into varbinary.
4 - The client side receives this serialized xml and restore it, then it trys to load into a generic XtraReport class.
So I would have to create and bound this assemblys at runtime, since we cannot relase a new version of our product every new report we built.
You need to make the MyCompleteReportDrawInDesignerMode class known by both solutions.
Make a separate class library assembly (separate project) that defines MyCompleteReportDrawInDesignerMode. This assembly (DLL) can then be referenced by both applications; the one that writes the report to an XML file and the one that reads this file and recreates the report.
the solution found was to create a class library visual studio solution, then we design the report, the subreports, and compile the all thing, and serialize the dll into a varbinary column in sql server. The dll is small, about 100 kbytes, so no problem.
After serialized into the database, the other application can consume the dll. In the same table, we put the namespace and class name from the main report, so you can create a instance at runtime, fill the datasource and print. I found that the xml serialization only works on the most recent devexpress versions, like: 13.1.10.
Here is the code:
Assembly local =
Assembly.LoadFile(#"C:\TempReports\5a788bc0-3e70-4f8b-8fa9-f180d23c4f03.dll");
Type t = _local.GetType("Relatórios_Teste.Reports.FluxoCaixa");
object test = Activator.CreateInstance(t);
var report = (XtraReport) test;
var controls = report.AllControls<XRSubreport>();
foreach (var control in controls)
{
if (control.Name.Equals("sub_detail"))
{
control.ReportSource.DataSource = GetSource();
control.ReportSource.DataMember = #"sp_test";
}
}
report.ShowPreview();
I'm quite new here, so please forgive me if I made any deviation from the rules of this website.
I'm trying to find the best way possible to manage the names of a stored procedure in code.
Currently when I'm calling a stored procedure I'm using this code:
public static DataSet GetKeyTables()
{
DataSet ds = new DataSet();
ds = SqlDBHelper.ExecuteMultiSelectCommand("Sp_Get_Key_Tables",
CommandType.StoredProcedure);
return ds;
}
But I don't think that stating the name of the stored procedure in code is a wise idea, since it will be difficult to track.
I thought about Enum or app.config solutions, but I'm not sure these are the best ways.
Any idea will be highly appreciated.
You can have a class with constant properties having names of the SPs.And have this class in a seperate class library (dll). Also it is not good to have sp_ as start of procedure see the link http://msdn.microsoft.com/en-us/library/dd172115(v=vs.100).aspx
public class StoredProcedures
{
public const string GetKeyTables = "Sp_Get_Key_Tables";
}
In the end, it always boils down to the concrete name string of the SP, no matter what you do. You have to keep them in sync manually. - No way around it...
You could use configuration files for that, but that additional effort will only pay when the names change frequently or they need to remain changeable after compilation.
You can wrap the calls in a simple gateway class:
public static class StoredProcedures
{
public static DataSet GetKeyTables()
{
return SqlDBHelper.ExecuteMultiSelectCommand(
"Sp_Get_Key_Tables",
CommandType.StoredProcedure);
}
public static DataSet GetFoobars()
{
return SqlDBHelper.ExecuteMultiSelectCommand(
"Sp_Get_Foobars",
CommandType.StoredProcedure);
}
}
Alternatively you can have POCOs that know how to interact with the database:
public class KeyTable
{
public int Id { get; set; }
// whatever data you need
public static List<KeyTable> GetKeyTables
{
var ds = SqlDBHelper.ExecuteMultiSelectCommand(
"Sp_Get_Key_Tables",
CommandType.StoredProcedure);
foreach (var dr in ds.Tables[0].Rows)
{
// build the POCOs using the DataSet
}
}
}
The advantage of this is that not only the SP name is kept in a unique place, but also the logic of how to extract data out of the dataset is in the same place.
I don't see a huge issue with what you are doing. You would need to store the SP name somewhere, so either in the query or in another config or helper function.
Depending on the specification, I tend towards a repository for CRUD operations, so I know all data access, including any SP calls, are in the ISomeRepository implementation.
When I work with stored procedures in C# I follow the following rules.
Every stored procedure is used only once in the code so that I have
only one place to update. I do hate Magic strings and avoid
them but stored procedures are used in Data Access Layer only once (e.g. Repositories, ReadQueries, etc).
For CRUD operations the pattern "sp_{Create/Read/Update/Delete}{EntityName}" is used.
If you want to have single place with all your stored procedures, you can create a static class with logic to create stored procedure's names.
How would I reference and pull data out of a generated dataset?
I have 2 projects in the same solution.
(1) MyUIProject
(2) MyDataSetProject
->MyGeneratedDataSet.xsd
-->-->MyNamesTable (in the dataset)
All I want to do is reference the MyNamesTable and loop through the names in the table and put them in a list box. I'm having trouble getting the records out of the generated dataset.
I'm trying to do something like:
foreach (var name in MyDataSetProject.GeneratedDataSet.MyNamesTable)
{
MyDropDownList.Items.Add(new ListItem(name));
}
Thanks for any thoughts.
First thing to do is make sure your references are correct between your projects. Right click on your MyUIProject and click Add Reference. Go to the Projects tab and add your MyDataSetProject entry. If it gives you an error about it already have been added, then it's already added.
Second, you need to access your dll project classes from your website. Let's say in your website you have a page called Default.aspx, and in your dll project you have a class called DataSetAccessor, which looks like the following:
public class DataSetAcessor
{
public DataSet GetDataSet(<arguments>)
{
//populate the dataset and return it
}
}
You can then use this class in your Default page:
//at top
using MyDataSetProject; //this may vary
//down in some method
DataSetAccessor dsa = new DataSetAccessor();
DataSet data = dsa.GetDataSet();
foreach(DataRow row in data.Tables[0].Rows)
{
//using the values in row to populate your drop down list
}
Hopefully this help.
I have a typed dataset in my project. I would like to populate a datatable with only one row instead of all rows. The selected row must be based on the primary key column. I know I could modify the designer code to achive this functionality however if I change the code in the designer I risk that this code will be deleted when I update my datased via designer in the future.
So I wanted to alter the SelectCommand not in the designer but just before firing up MyTypedTableAdapter.Fill method. The strange thing is that the designer does not create a SelectCommand! It creates all other commands but not this one. If it would create SelectCommand I could alter it in this way:
this.operatorzyTableAdapter.Adapter.SelectCommand.CommandText += " WHERE MyColumn = 1";
It is far from perfection but atleast I would not have to modify the designer's work. unfortunately as I said earlier the SelectCommand is not created. Instead designer creates something like this:
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
private void InitCommandCollection() {
this._commandCollection = new global::System.Data.SqlClient.SqlCommand[1];
this._commandCollection[0] = new global::System.Data.SqlClient.SqlCommand();
this._commandCollection[0].Connection = this.Connection;
this._commandCollection[0].CommandText = "SELECT Ope_OpeID, Ope_Kod, Ope_Haslo, Ope_Imie, Ope_Nazwisko FROM dbo.Operatorzy";
this._commandCollection[0].CommandType = global::System.Data.CommandType.Text;
}
It doesn't make sense in my opinion. Why to create UpdateCommand, InsertCommand and DeleteCommand but do not create SelectCommand? I could bear with this but this._commandCollection is private so I cannot acces it outside of the class code.
I don't know how to get into this collection without changing the designer's code. The idea which I have is to expose the collection via partial class definition. However I want to introduce many typed datasets and I really don't want to create partial class definition for each of them.
Please note that I am using .NET 3.5.
I've found this article about accessing private properties but it concerns .NET 4.0
Thanks for your time.
In the Dataset designer, first configure a Table/Adapter pair with the basic (all rows) query. Make sure it works and updates/deletes etc.
Then right-click, "Add Query" and change the SQL text to include a "WHERE MyId = #Id". Make sure you keep the same columns. Select Next and call the generated method "FillById()".
Ad of course, use FillById(id) instead of Fill() at the right places.