Fastest way to assign properties to class from datarow C# - c#

Right now Im working in a big project, So theres a lot of data and tables going around.
For best practices Im creating a class for every table and object
Its goes like this:
public class Employee
{
private String Name;
public String Name
{
get
{
return Name;
}
set
{
Name = value;
}
}
public Employee(int EmployeeID)
{
/*
GET DATA ROW AND ASSIGN IT TO EVERY PROPERTIE
*
* Name = row("name")
* AND DO THIS FOR EVERY PROPERTIE!
*
*/
}
}
So whats happening here is that I have to assign every propertie from a query in the class constructor.
But imagine a table with like 50+ columns, I have to do this 50+ times and this takes a lot of time.
Theres a way to automate this automate the creation of the 50+ properties and the asignation of the 50+ properties in the class withouth taking a lot of time.
I just wanna find a way to create a class automating the properties assignation from a datarow instead of writting all the columns string to the properties. Something like Entityt Framework but done by me.
Greeting and thanks

There are heaps of examples online to make C# classes from dB tables & stored procedures, research that and POCO's, eg:
Generate class from database table
http://www.codeproject.com/Articles/8397/C-Code-Generator-for-Stored-Procedures
You're not the first to encounter this, best to do a quick google next time.

you should use better entity framework code first approach, it works even if your database is already created.
use a tool to generate the class model, and create a context like:
public class MyContext : DbContext
{
public MyContext (){}
public DbSet<MyModel> MyModel { get; set; }
}

Related

DevExpress Many-To-Many Association table

I posted this question at DevExpress support, nevertheless I know that here I might get answers more quickly, this is a super big issue for me and I have been pulling my hairs for 2 days without any success. Hopefully people here might have experience in this framework.
My problem is related to the association table that is created by default when an M-N relation exists between two Business Objects.
Idea is so:
Lets assume I have these objects -> UNITS and USERS
For each USER within a UNIT I need to store a STATUS, hence I created a new attribute from SQL , called STATUS_IN_UNIT
The problem arises when I want to access this property programatically,
which of course is impossible since I do not have any object
associated to this table. Only way is to access it through querying
database.
What I want to achieve is to show this table as in a ListView inside
the UNIT DetailView, this is MANDATORY since USERS attached to a UNIT
must be enabled and disabled. I have seen these threads
https://www.devexpress.com/Support/Center/Example/Details/E2334
https://www.devexpress.com/Support/Center/Question/Details/T500887
but then again I am looking for a more trivial solution to this,
otherwise it would be really time consuming to create views and
controllers my self in order to handle it. So my questions are as
below:
1. How to create a class that references to THIS table ?
2. How to show THIS table inside UNITS DetailView and access its properties from the above table?
It would be greatly appreciated if you would answer this question.
Thank you in advance !!!
I assume you have created a user class and create a collection of Unit in it, and a collection user inside Unit class. In that case, XAF will create an auto-created intermediate table called Users_Units which holds both primary key and you can not add any attributes inside it. If you want to add an attribute(s) or property inside the intermediate class, you should create the class explicitly, so here's the code:
public class User : BaseObject
{ //... your code here
[Association("User-UserUnits")]
public XPCollection<UserUnit> UserUnits
{
get
{
return GetCollection<UserUnit>("UserUnits");
}
}
}
public class Unit : BaseObject
{ // ... your code here
[Association("Unit-UserUnits")]
public XPCollection<UserUnit> UsersUnitss
{
get
{
return GetCollection<UserUnit>("UserUnits");
}
}
}
public class UserUnit : BaseObject
{
User user;
[Association("User-UserUnits")]
public User User
{
get
{
return user;
}
set
{
SetPropertyValue("User", ref user, value);
}
}
Unit unit;
[Association("Unit-UserUnits")]
public Unit Unit
{
get
{
return unit;
}
set
{
SetPropertyValue("Unit", ref unit, value);
}
}
int status;
public int Status
{
get
{
return status;
}
set
{
SetPropertyValue("Status", ref status, value);
}
}
}
But of course with above code you can not link/unlink each other between User and Unit directly. Instead, you should add the detail record manually as it acts as a normal master-detail or one-to-many entity relationship.

Change object type in EntityFramework

I'm working on a desktop application using C# and EF6.
For some reasons (One would be the complexity of the structure of the models) I've decided to use only on DbContext for the whole project, instead of create and dispose every time I need to add, update, delete or fetch any data.
Let's say I have 2 Models
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CollegeStudent : Student
{
public string Course { get; set; }
}
I have an ObservableCollection in the ViewModel and instantiate it after I add an item to the collection.
I add and Student object to the database in the following way
public void AddStudent()
{
var obj = new Student() { Name = "Mike" };
_context.Set<Student>().Add(obj);
StudentCollection = new ObservableCollection<Student>(_context.Set<Student>().ToList());
}
And when I want to change the type of the Student to the CollegeStudent I use the following piece of code
public void AddCollegeStudent(CollegeStudent obj)
{
var original = _context.Set<Student>().Find(obj.Id);
var obj = new Student()
{
Id = original.Id,
Name = original.Name,
Course = "Some Course",
}
_context.Database.ExecuteSqlCommand("INSERT INTO CollegeStudent (Id, Course) VALUES (obj.Id, '" + obj.Course + "');");
StudentCollection = new ObservableCollection<Student>(_context.Set<Student>().ToList());
}
It perfectly works and insert the CollegeStudent details in the database but when getting the list of students from the database it throws the following
exception:
All objects in the EntitySet 'Students' must have unique primary keys. However, an instance of type 'CollegeStudent' and an instance of type 'Student' both have the same primary key value, 'EntitySet=Students;Id=4'
I've decided to use only on DbContext for the whole project, instead of create and dispose every time I need to add, update, delete or fetch any data.
There's your problem...
This is one reason why you shouldn't you a single DbContext for an entire app - changes to underlying data can make the data in your context invalid. Contexts are meant to be created and disposed with every DB operation. They are lightweight so creating lots of them shouldn't be a big problem.
I realise you are likely trying to keep things as straightforward as possible but it might be worthwhile separating your concerns sooner rather than later.
Assuming this is a XAML UI you could make use of a framework like MVVM Light or Prism
https://mvvmlight.codeplex.com
https://msdn.microsoft.com/en-us/library/ff648465.aspx
If not the basics are you want some kind of mediator (http://www.blackwasp.co.uk/mediator.aspx)
So the idea is you will have some kind of service class that makes a call to save the data, then raises the message/event saying that the data was updated.
You would register a handler for when that event is raises to update the view model accordingly.
Hope this makes sense.

Prevent EF 5 from generating a property

I'm using EF5 database first with partial classes. There's a property in my partial class which contains n object which is stored as a column in my database containing XML data. I want to handle the serialization/deserialization of this object when the EF tries to read/write it with a custom getter/setter.
Is it possible to expose the column in my partial class and map it using the EF, without auto-generating a property for it?
ie:
public SomeObject BigComplexObject { get; set; } // forms etc in my app use this
public string BigComplexObjectString // when the EF tries to read/write the column, my custom getter/setter kicks in
{
get { return this.BigComplexObject.ToXmlString(); }
set { this.BigComplexObject = new BigComplexObject(value); }
}
At present, the EF is auto-generating a member for the column so I'm left with two.
Try to change the logic. Leave EF generated property that will be populated with XML string from the database:
public string BigComplexObjectString { get; set; }
Then do the following:
[NotMapped]
public SomeObject BigComplexObject
{
get { return new SomeObject(this.BigComplexObjectString); }
set { this.BigComplexObjectString = value.ToXmlString(); }
}
Don't forget to add [NotMapped] to instruct EF to ignore this property.
Well, we use a little trick for a quite similar case...
We use the property panel (in the edmx file) of our... properties and add something in the "documentation" (summary or long description) line (probably not the best place, but anyway). This can be access by your T4 file.
So you could write something like "useXml" in the property panel, then modify your tt to generate the desired code when (example to get the info in the .tt file)
if (edmProperty.Documentation != null && edmProperty.Documentation.Summary = "useXml")
//generate something special
It would be great to have a better place for "cusom infos" in the edmx, but we didn't find anything better for instant.

Setting what table a DbContext maps to

In an application I'm working on, I have what are essentially a bunch of lookup tables in a database which all contain two things: The ID (int) and a Value (string).
There's only a handful of them, but I want to map all of them to a single Context which depends on the table name. Something like:
class LookupContext : DbContext
{
public DbSet<Lookup> Lookups { get; set; }
public LookupContext(String table)
{
// Pseudo code:
// Bind Lookups based on what table is
Lookups = MyDatabase.BindTo(table);
}
}
So if I create a new LookupContext("foo"), it binds against the foo table. If I do new LookupContext("bar") it uses the bar table, and so forth.
Is there any way to do this? Or do I have to create a separate context + model for every table I have?
This is more or less my first time doing this, so I'm not really sure if what I'm doing is right.
The answer we should be able to give you is to use enums, but that's not available quite yet - it's in the next version of EF. See here for details: http://blogs.msdn.com/b/adonet/archive/2011/06/30/walkthrough-enums-june-ctp.aspx
With earlier versions of EF, you can simply create a class per lookup value (assuming state as an example) and have code that looks something like the following:
public class State
{
public int StateId {get;set;}
public string StateName {get;set;}
}
public class LookupContext : DbContext
{
public DbSet<State> States {get;set;}
// ... more lookups as DbSets
}
This will allow you to use one context but will still require one class per table. You can also use the fluent API if you want your table/column names to differ from your class/property names respectively. Hope that helps!
I actually realized I was completely over complicating things beyond reason. There was no reason for storing multiple tables with two columns.
I'm better off storing my data as:
public class LookupValue
{
public string LookupValueId { get; set; }
public string Value { get; set; }
public string LookupType { get; set; }
}
Where the third field was simply the name of the table that I was previously storing in the database.
I'm still interested in the idea of mapping a single Context class to multiple tables, but I believe what I described above is the least convoluted way of accomplishing what I need.

What is the quickest way to query a database with LINQ?

I'm reading a WROX book on LINQ and the author is performing LINQ on a database. Essentially he is accessing the database as an object as shown in the code below.
But I don't see how he expects to "access the database as an object", even the downloaded code gets an error on "db.DirectoryInformation" saying "DirectoryInformation" is unknown.
What am I missing? I would think I first need to create LINQ-to-SQL classes or an ADO.NET EDM or is there even a more direct way to hook LINQ up to a database, i.e. just by creating a database class and that inherits from DataContext?
AdventureWorks db = new AdventureWorks("Integrated Security=sspi");
...
[Database(Name = "AdventureWorks")]
public class AdventureWorks : DataContext
{
//public Table<DirInfo> DirectoryInformation;
public AdventureWorks(string connection) : base(connection) { }
public Table<DirectoryInformation> DirectoryInformation;
}
You can download the whole code here, chapter 1, LINQ.sln.
Look at the end of the Form1.cs source file, the LINQ to SQL database is declared using attributes:
[Database(Name = "AdventureWorks")]
public class AdventureWorks : DataContext
{
//public Table<DirInfo> DirectoryInformation;
public AdventureWorks(string connection) : base(connection) { }
public Table<DirectoryInformation> DirectoryInformation;
}
[Table(Name = "DirectoryInformation")]
public class DirectoryInformation
{
[Column(DbType="varchar(50)")]
public string DirectoryName;
[Column(DbType = "varchar(255)")]
public string DirectoryDescription;
}
Providing the settings with the project define a connection string, this is all you need for a simple mapping of the DirectoryInformation type to the DirectoryInformation table in the AdventureWorks database.
Oh, absolutely you can use vanilla objects with LINQ-to-SQL; you don't even need to subclass DataContext - but you do need to tell it about your model. This is often done with attributes on members (for columns) and types (for tables), but can also be done with an external mapping file (xml). I wonder if they are just over-abbreviating for simplicity... for example, I suspect that the table should be a property:
public Table<DirectoryInformation> DirectoryInformation {
get { return GetTable<DirectoryInformation>(); }
}
The whole "dbml" thing is just there as a designer tool to help you generate the classes; the important code is just decoracted classes (with some conventions on things like navigation properties to make life simper to use). That said, for "quickest": use the designer.

Categories

Resources