How do i pass my class as parameter (Entity Framework 6) - c#

I am having quite some trouble passing the Class type as paramater, since they represent tables and i only want to retrieve the result as a list
My function that takes the list is setDados(ds)
public void setDados(List<RP_EntityFrameWork_Tentativa.marcas> data)
{
gridControl1.DataSource = data;
gridView1.PopulateColumns();
Debug.WriteLine(data);
}
Which i have to before hand specify what class the list type is.
is there a way to be able to declare something along the lines of List<Class> or just pass a class as a parameter ?
all the classes i need to pass follow this same "Template"/Writing Style
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RP_EntityFrameWork_Tentativa
{
public class marcas
{
[Key]
[Required]
[StringLength(50)]
public string Marca { get; set; }
[StringLength(50)]
public string Descmarca { get; set; }
[StringLength(50)]
public string Nat { get; set; }
//ligação carros
public virtual ICollection<carros> carros{ get; set; }
}
}
i am currently using the following method
private void abreListaGeral(DevExpress.XtraEditors.ButtonEdit txt, List<marcas> ds, bool multiselect, int mode, int indexProcura)
{
this.Cursor = Cursors.WaitCursor;
String str = "";
frmQueryList lista = new frmQueryList();
lista.multiselect = multiselect;
lista.mode = mode;
lista.indexProcura = indexProcura;
lista.btnNovo.Visibility = DevExpress.XtraBars.BarItemVisibility.Never;
lista.btnNovo.Enabled = false;
lista.setDados(ds);
lista.ShowDialog();
str = lista.resultado2;
txt.Text = lista.resultado;
lista.frmIniciado = false;
lista.Close();
this.Cursor = Cursors.Default;
}
Which works but i have to create a new method for every Class i need to use this way create a bunch of overrites and useless code that could surely be optimized
What i am looking for is to have abreListaGeral() take as arguments such as List<marcas> List<carros> List<etc> without having to previously specify it

Related

Traversing an XML file using Linq to XML not working as expected

Sorry for the somewhat basic question, but what can I say. I can't figure it out. The problem is that there's a foreach loop that's supposed to iterate through the rows (sections) and while it works for the first section, the second time through the loop it doesn't seem to read the second section. The same data is stored in version. BTW, the way the method is called I would be passing in ProductName as a parameter (There will be multiple products represented here and also a version number (e.g. v2.0.0) that I'll need to filter the results for too.
So I have an XML file that looks like this:
<Products>
<ProductName1>
<v2.0.0>
<GUID>"{B5ECEC43-5406-4E4D-96D9-456823100313}"</GUID>
<VersionNameToUninstall>"2.0.0 - 2.0.2"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.0.0-Uninst.iss"</UninstallResponseFile>
</v2.0.0>
<v2.0.3>
<GUID>"{1D6C02D7-8E87-43BE-8AB2-1FF0E5ACD410}"</GUID>
<VersionNameToUninstall>"2.0.3"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.0.3-Uninst.iss"</UninstallResponseFile>
</v2.0.3>
</ProductName1>
<ProductName2>
<v3.0.0>
<GUID>"{ABCDEC43-5406-4E4D-96D9-456823101234}"</GUID>
<VersionNameToUninstall>"2.2.0 - 2.2.2"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-2.2.0-Uninst.iss"</UninstallResponseFile>
</v3.0.0>
<v4.0.0>
<GUID>"{5D6C02D7-8E87-43BE-8AB2-1FF0E5ACD589}"</GUID>
<VersionNameToUninstall>"4.0.0"</VersionNameToUninstall>
<UninstallResponseFile>"GVQC-Client-4.0.0-Uninst.iss"</UninstallResponseFile>
</v4.0.0>
</ProductName2>
</Products>
There will only be 10 or so versions (e.g. v2.x.x) so there's not a lot of data here. So I created a multidimensional (nested) class/struct to hold the data and when I try my code to read the data it's not working.
Here are the classes/stucts (I've tried both and neither works) that I'm trying to populate:
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row {get;set;}
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
So here's my code. Please just ignore the Stream - that's so I can embed this XML file in the .exe and not have it be a separate file:
public static List<TopLevelObject> GetGUIDSFromFile(string GUIDKey)
List<InstallScriptMSIXMLTopLevelObject> installScriptMSIXMLTopLevelObjectList = new List<InstallScriptMSIXMLTopLevelObject>();
Stream GUIDXmlFileStream = typeof(PGCommonCA).Assembly.GetManifestResourceStream("PGCommonCA.ProductGUIDs.xml");
XElement xElement = XElement.Load(GUIDXmlFileStream);
var versions = xElement.Elements(GUIDKey).Descendants();
foreach (var version in versions)
{
TopLevelObject topLevelObject = new TopLevelObject();
RowLevelObject rowLevelObject = new RowLevelObject();
TopLevelObject.Version = version.Name.LocalName;
RowLevelObject.Guid = version.Element("GUID").Value;
RowLevelObject.VersionName = version.Element("VersionNameToUninstall").Value;
RowLevelObject.UninstallFileName = version.Element("UninstallResponseFile").Value;
TopLevelObjectList.Add(topLevelObject);
}
return TopLevelObjectList;
}
I know there are many ways to read XML and my choice doesn't work so I'm looking for another simple solution.
The following works :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement productName = doc.Root;
List<TopLevelObject> top = productName.Elements().Select(x => new TopLevelObject() {
Version = x.Name.LocalName,
Row = new RowLevelObject() {
Guid = (string)x.Element("GUID"),
VersionName = (string)x.Element("VersionNameToUninstall"),
UninstallFileName = (string)x.Element("UninstallResponseFile")
}
}).ToList();
}
}
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row { get; set; }
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
}
I figured it out (many thanks to jdweng!!). Here's the final solution based on the revised XML at the top:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static TopLevelObject GetInfo(string xmlKey)
{
XDocument doc = XDocument.Load(FILENAME);
XElement productName = doc.Root;
List<TopLevelObject> top = productName.Descendants(xmlKey).Elements().Select(x => new TopLevelObject() {
Version = x.Name.LocalName,
Row = new RowLevelObject() {
Guid = (string)x.Element("GUID"),
VersionName = (string)x.Element("VersionNameToUninstall"),
UninstallFileName = (string)x.Element("UninstallResponseFile")
}
}).ToList();
}
}
public class TopLevelObject
{
public string Version { get; set; }
public RowLevelObject Row { get; set; }
}
public struct RowLevelObject
{
public string Guid { get; set; }
public string VersionName { get; set; }
public string UninstallFileName { get; set; }
}
}

How to change the order properties are serialized in C#

I have a list in C# with 4 items. This list is used to send a response in a web service and I need a specific order for the items, but I'm having a problem because, for some reason, the list changes the order when I fill it.
First, this is the class of the list
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace Mvm.SATWeb.Domain
{
[Serializable, DataContract]
public class puntoDeAtencion
{
public puntoDeAtencion()
{
}
[DataMember]
public string codigoPuntoAtencion { get; set; }
[DataMember]
public decimal montoIngreso { get; set; }
[DataMember]
public decimal montoEgreso { get; set; }
[DataMember]
public decimal ingresoNeto { get; set; }
}
}
I use a SQL server query to fill the list with a dataset
List<puntoDeAtencion> valores = new List<puntoDeAtencion>();
DataSet ds;
Database baseDatos = DatabaseFactory.CreateDatabase();
DbCommand comandoConsulta = baseDatos.GetStoredProcCommand("USP_RiesgoLiqui");
comandoConsulta.CommandTimeout = 600000;
baseDatos.AddInParameter(comandoConsulta, "#pvstrIdAgencia", DbType.String, "-1");
baseDatos.AddInParameter(comandoConsulta, "#pvstrFechaInicial", DbType.String, FechaIni);
baseDatos.AddInParameter(comandoConsulta, "#pvstrFechaFinal", DbType.String, FechaFin);
comandoConsulta.CommandTimeout = 1000000;
// baseDatos.ExecuteDataSet();
ds = baseDatos.ExecuteDataSet(comandoConsulta);
if (ds.Tables.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count ; i++)
{
// valores.Add(s)
//valores.Add (new punptoDeAtencion(){}
valores.Add(new puntoDeAtencion() { codigoPuntoAtencion = Convert.ToString(ds.Tables[0].Rows[i]["Agencia"]), montoIngreso = Convert.ToDecimal(ds.Tables[0].Rows[i]["INGRESONETO"]), montoEgreso = Convert.ToDecimal(ds.Tables[0].Rows[i]["MONTOEGRESO"]), ingresoNeto = Convert.ToDecimal(0.00) });
// var list1 = (from p in ds.Tables[0].Rows[i] select p).ToList();
}
}
return valores.ToList<puntoDeAtencion>();
This is the response (Using SOAP UI, but when I debug show the same values in the response object)
<b:listaPuntosDeAtencion>
<b:puntoDeAtencion>
<b:codigoPuntoAtencion>001</b:codigoPuntoAtencion>
<b:ingresoNeto>0</b:ingresoNeto>
<b:montoEgreso>53266155.0000</b:montoEgreso>
<b:montoIngreso>138285187.0000</b:montoIngreso>
</b:puntoDeAtencion>
and this is how it should be
<listaPuntosDeAtencion>
<puntoDeAtencion>
<codigoPuntoAtencion>00654</codigoPuntoAtencion>
<montoIngreso>79000.0</montoIngreso>
<montoEgreso>30000.0</montoEgreso>
<ingresoNeto>0.0</ingresoNeto>
</puntoDeAtencion>
I want to order the list or the response, I don't know if LINQ works in this case.
You can order them by using Order on DataMember like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace Mvm.SATWeb.Domain
{
[Serializable, DataContract]
public class puntoDeAtencion
{
public puntoDeAtencion()
{
}
[DataMember(Order = 0)]
public string codigoPuntoAtencion { get; set; }
[DataMember(Order = 1)]
public decimal montoIngreso { get; set; }
[DataMember(Order = 2)]
public decimal montoEgreso { get; set; }
[DataMember(Order = 3)]
public decimal ingresoNeto { get; set; }
}
}
Documentation here: https://msdn.microsoft.com/en-us/library/ms729813.aspx

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. Insert to table

im learning ORM in c#. When I`m adding register to Register table the error is displayed.
My classes are.
using System;
using System.Collections.Generic;
using System.Linq;using System.Text;
namespace PreSchool
{
public class Child
{
public int ChildId {get; set;}
public string Name { get; set; }
public string Surname { get; set; }
public virtual List<Register> Registers { get; set; }
public Child()
{
this.Registers = new List<Register>();
}
}
AND
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
namespace PreSchool
{
public class Register //partial
{
public int RegisterId { get; set; }
public DateTime dt_in { get; set; }
public DateTime dt_out { get; set; }
public virtual Child Child { get; set; }
}
}
Function
private void button1_Click(object sender, RoutedEventArgs e)
{
using (var db = new ChildContext())
{
Child bla= ChildrenGrid.SelectedItem as Child ;
var reg = new Register() { dt_in = DateTime.Now, dt_out = DateTime.Now };
bla.Registers.Add(reg);
db.SaveChanges();
}
}
Earlier I had a problem and I had to add "partial" in Register Class to compile the project but now its not necesarry ( why?). The error from subject dipslays in this place : bla.Registers.Add(reg);
Thanks for any help !
It appears as though you are trying to add the Register object to a disposed context. If you are binding records to a grid then they will no longer be attached to the DB when you retrieve them, you need to re-pull the object and update that instead e.g.
using (var db = new ChildContext())
{
// get the id of the selected child
var childId = (ChildrenGrid.SelectedItem as Child).ChildId;
// pull that record from the "live" context
Child entity = db.Child.Single(x => x.ChildId == childId);
// add the new record to the "live" entity
entity.Registers.Add(new Register
{
dt_in = DateTime.Now,
dt_out = DateTime.Now
});
db.SaveChanges();
}
FYI - it's generally a better idea to use view models for your UI rather than actual DB entities.

How to bind an advBandedGridView at run time?

I am new in the using of DevExpress. I need to design and bind a complex DataGrid.
I have designed it using the Designer. The datagrid is of type Master-Detail, and it contains the 'MainGrid' and other detail grids. One of them is of type: 'advBandedGridView'
The design of the MainGrid is as shown below:
And the design of the 'advBandedGridView' is as follows:
Now, I need to fill my DataGrid using Lists collections, so I used the following Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void simpleButton1_Click(object sender, EventArgs e)
{
ArrayList a = new ArrayList();
Term_Space_Grid t = new Term_Space_Grid("x", "y", true, "z");
t.expansions = new List<MyExpansions>();
t.expansions.Add(new MyExpansions(0, "Aya", 0, 0, 0, 0, 0));
a.Add(t);
resultsGridControl.DataSource = a;
}
}
public class Term_Space_Grid
{
public string x { get; set; }
public string y { get; set; }
public string g { get; set; }
public bool z { get; set; }
public List<MyExpansions> expansions { get; set; }
public Term_Space_Grid(string x, string y, bool z, string g)
{
this.x = x;
this.y = y;
this.z = z;
this.g = g;
}
}
public class MyExpansions
{
public Morphos morphos { get; set; }
public Semantics semantics { get; set; }
public MyExpansions(int morphoID, string morphoDerivation, int synID, int subID, int supID, int hasID, int insID)
{
this.morphos = new Morphos(morphoID, morphoDerivation);
this.semantics = new Semantics(synID, subID, supID, hasID, insID);
}
}
public class Morphos
{
//public List<Morph> morph{ get; set; }
public Morph morph { get; set; }
public Morphos(int morphoID, string morphoDerivation)
{
//this.morph = new List<Morph>();
//this.morph.Add(new Morph(morphoID, morphoDerivation));
this.morph = new Morph(morphoID, morphoDerivation);
}
}
public class Semantics
{
public List<Sem> synonyms { get; set; }
public List<Sem> subClasses { get; set; }
public List<Sem> superClasses { get; set; }
public List<Sem> hasInstances { get; set; }
public List<Sem> instanceOf { get; set; }
public Semantics(int id1,int id2, int id3, int id4, int id5 )
{
this.synonyms = new List<Sem>();
this.subClasses = new List<Sem>();
this.superClasses = new List<Sem>();
this.hasInstances = new List<Sem>();
this.instanceOf = new List<Sem>();
this.synonyms.Add(new Sem(id1));
this.subClasses.Add(new Sem(id2));
this.superClasses.Add(new Sem(id3));
this.hasInstances.Add(new Sem(id4));
this.instanceOf.Add(new Sem(id5));
}
}
public class Morph
{
public int MorphoID { get; set; }
public string MorphoDerivation { get; set; }
public Morph(int morphoID, string morphoDerivation)
{
this.MorphoID = morphoID;
this.MorphoDerivation = morphoDerivation;
}
}
public class Sem
{
public int SemID { get; set; }
//public string MorphoDerivation { get; set; }
public Sem(int semID)
{
this.SemID = semID;
}
}
}
However, I found that the result is built as a new DataGrid that has not any designed form. I mean that the detail tabs that I define in the Designer are not appeared in the resulted grid.
The result is as follows:
Notes
The design of the resulted grid which is totally different from my design, I think it is just like the Lists objects.
The other problem which is the appearance of :
"WindowsFormsApplication2.Morphos" and "WindowsFormsApplication2.Semantics" at the cells of the grid rather than the values that I passed!
Firstly, you should create associations between your data object properties and GridView columns via GridColumn.FildName property.
For your main view (gridView2) it looks like this:
// gridColumn1
this.gridColumn1.Caption = "ID";
this.gridColumn1.FieldName = "x"; // associate this column with Term_Space_Grid.x property
this.gridColumn1.Name = "gridColumn1";
Please read the following article for more details: Creating Columns and Binding Them to Data Fields
Secondly, you can not directly bind columns to object's nested properties (for example to MyExpansions.semantics.subclasses.SemID).
To bypass this restriction you can use several approaches:
The simplest approach is using Unbound Columns and the corresponding ColumnView.CustomUnboundColumnData event (you can handle this event to provide data from nested objects).
You can also use the approach demonstrated in the following KB article: How to display and edit complex data properties in grid columns
Thirdly, to get official and guaranteed answer you should address any urgent question related to any DevExpress products directly to DevExpress Support Center.

Outputting Class Of Stored Values To List

This loads a set of values from an XML file and places them into a class for storage. I'm trying to figure out how to output the values as a list so I can place them into a Listbox.
I thought there would be an easy way like a .ToList() method or to be able to foreach through the strings in the class (no public GetEnumerator). I've been able to find out that Foreach hides some of the complexity but not away to do what I want.
I've been searching online with no avail (lacking the correct terminology maybe), unfortunately I left my C# reference books at work :/
Would much appreciate a pointer in the right direction,
Thanks.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
namespace ThereIsOnlyRules
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
try
{
listBox1.Items.Clear();
string path = "characterXML.xml";
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
System.Xml.XmlDocument CXML = new System.Xml.XmlDocument();
CXML.Load(fs);
//Get the number of elements
XmlNodeList elemList = CXML.GetElementsByTagName("unit");
//foreach (var element in elemList)
//{
// listBox1.Items.Add(element);
//}
for (int i = 0; i < elemList.Count; i++)
{
UnitAttributes attributes = new UnitAttributes();
attributes.army = elemList[i].Attributes["army"].Value;
attributes.category = elemList[i].Attributes["category"].Value;
attributes.type = elemList[i].Attributes["type"].Value;
attributes.composition = elemList[i].Attributes["composition"].Value;
attributes.WS = elemList[i].Attributes["WS"].Value;
attributes.BS = elemList[i].Attributes["BS"].Value;
attributes.T = elemList[i].Attributes["T"].Value;
attributes.W = elemList[i].Attributes["W"].Value;
attributes.I = elemList[i].Attributes["I"].Value;
attributes.A = elemList[i].Attributes["A"].Value;
attributes.LD = elemList[i].Attributes["LD"].Value;
attributes.save = elemList[i].Attributes["Save"].Value;
attributes.armour = elemList[i].Attributes["armour"].Value;
attributes.weapons = elemList[i].Attributes["weapons"].Value;
attributes.specialrules = elemList[i].Attributes["specialrules"].Value;
attributes.transport = elemList[i].Attributes["transport"].Value;
attributes.options = elemList[i].Attributes["options"].Value;
//foreach (string item in attributes)
//{
//unit.Add(item);
//}
//listBox1.Items.AddRange(attributes)
}
//Close the filestream
fs.Close();
}
catch (Exception ex)
{
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ThereIsOnlyRules
{
class UnitAttributes
{
public string army { get; set; }
public string category { get; set; }
public string type { get; set; }
public string composition { get; set; }
public string WS { get; set; }
public string BS { get; set; }
public string T { get; set; }
public string W { get; set; }
public string I { get; set; }
public string A { get; set; }
public string LD { get; set; }
public string save { get; set; }
public string armour { get; set; }
public string weapons { get; set; }
public string specialrules { get; set; }
public string transport { get; set; }
public string options { get; set; }
}
}
<?xml version="1.0"?>
<config>
<unit
army="Tyranids"
category="Troops"
type="Infantry"
composition="10-30"
WS="3"
BS="3"
T="3"
W="1"
I="4"
A="1"
LD="6"
Save="6+"
armour="Chitin"
weapons="Claws and Teeth, Fleshborer"
specialrules="Instictive Behaviour - Lurk, Move Through Cover"
transport="If the brood consists of 20 models or less, it may take a Mycetic Spore."
options="Strangleweb, Spinefists, Spike rifle, Devourer, Adrenal Glands, Toxin Sacs"
>
Termagant Brood
</unit>
<unit
army="Tyranids"
category="Troops"
type="Infantry"
composition="10-30"
WS="3"
BS="3"
T="3"
W="1"
I="5"
A="2"
LD="6"
Save="6+"
armour="Chitin"
weapons="Scything Talons"
specialrules="Instictive Behaviour - Feed, Bounding Leap, Fleet, Move Through Cover"
transport="If the brood consists of 20 models or less, it may take a Mycetic Spore."
options="Adrenal Glands, Toxin Sacs"
>
Hormagaunt Brood
</unit>
</config>
Are the members of your class fields or properties? Either way, a little reflection and Linq should allow you to enumerate through the data members of your class, after you have hydrated an instance of it from your XML file.
var fieldDictionary =
(from f in typeof(UnitAttributes).GetFields()
select new {Name = f.Name, Value = (string)(f.GetValue(attributes))})
.ToDictionary(x=>x.Name, x=>x.Value);
fieldDictionary is now a Dictionary<string, string> (which is an IEnumerable<KeyValuePair<string, string>>), which should be suitable for loading into a ListBox.
Be advised; reflection is slow. It would be far more preferable for you to modify or extend your UnitAttributes class to implement IEnumerable (probably of a Tuple, maybe a KeyValuePair). It would also allow you to enumerate the properties of an instance of the class in exactly the order you want, instead of the order in which they're defined, or by some other FieldInfo/PropertyInfo data like the field's name.
Also be aware that a field is not a property, and vice versa. If you have a mix of properties and public fields on your class, I would HIGHLY recommend standardizing to one or the other; otherwise you'll have to reflect BOTH a list of properties and a list of fields using two of the above Linq statements (at a cost of roughly double the run time), and there will be no chance of them being in any custom-defined order.
You'll save yourself a lot of time and effort if you use a common serializer like XmlSerializer to handle converting your objects to/from strings. You don't have to write this type of code from scratch.

Categories

Resources