EF6 Get entity with list property from stored procedure - c#

My stored procedure returns a joined table like:
Employee Department
-------------------
John IT
Bob IT
Rob IT
Jane Sales
Mary Sales
I have the appropriate entities generated by EF:
class Employee
{
public int Id {get;set;}
public string Name{get;set;}
public int DepartmentId{get;set;}
public Department Deparment{get;set;}
}
class Department
{
public int Id {get;set;}
public string Name{get;set;}
public ICollection<Employees> Employees{get;set;}
}
I execute the stored procedure like this:
Database.SqlQuery<Department>("exec spGetDepartments").ToList();
And the result is a list of departments:
IT
IT
IT
Sales
Sales
Each has empty list of employees.
Can I have the 2 department entities with lists of corresponding employees?
The example is simplified, but the business requirement is use stored procedure as there is a complicated logic which is hard to replicate in LINQ.

You cannot employ the navigation properties on stored procedures.
Note the stored procedure doesn't actually employ a context method call, but an actual query execution.
You have to use the DBcontext, to accomplish the task you require.
Stored procedures aren't "composable".
The "Lazy loading" or its variants are only available via a context.
You could in theory achieve a read statement in a generic repository pattern, if you absolutely wanted to. It might even be efficient under some circumstances.
But in that case, your resultset on the stored procedure, would always have to hold your entire row set.
The behavior would be quite complicated. I wouldn't actually advise it. It might be possible, but smart? decidedly not.

Related

Stored procedure in Entity Framework database first approach

I am doing transition for a project from Webforms to MVC application using Entity Framework database first approach and have database ready along with all stored procedures in place.
I successfully created an .edmx file and was able to use my stored procedures and it worked great when there was any insert or update operation to perform. But the real problem occurred when I was using select query in one of my stored procedures.
For example, there is an Employee table which has following columns:
EmpId, FirstName, LastName, Age, Salary
I have a stored procedure GetAllEmpDetails which has following select query.
Select
EmpId, (FirstName + ' ' + LastName) as FullName, Salary
from
Employee
Now when I am trying to bind the result of this stored procedure with the Employee class which has 5 properties as per the table structure, then I am getting an error that value for Age property is expected but it is not available in the resultset.
I know there is no FullName property as well, so my question is how to solve this problem with the model class generated (as in this case Employee) so that it can tackle these dynamism?
How to map a stored procedure in EF?
Since you are doing Database First Approach and you have an EDMX file, let EF generate the class of the stored procedure result for you. You may have many stored procedures and you want to avoid creating the classes manually: After all that is the whole point of using an ORM tool. Also some of your stored procedures may have parameters. Doing it the way below will handle all that for you. It is actually pretty simple.
To get EF to do this for you, follow the steps to below:
Double click your EDMX file
Choose Update Model from Database
You will see the dialog similar to below:
Make sure you have checked the boxes as shown.
That will add the stored procedure and you will see it in your model browser as shown below:
If you want to change the class name auto-generated by EF then do so. I strongly suggest you do this and give your class a meaningful names that follow .NET naming conventions. The convention I follow is remove any verbs from the stored procedure name and append the word result to the end. So you will end up with name as shown below:
Press OK
Some Notes
This is much better than writing the classes manually in case your stored procedure name, or the parameters it needs, or the result it returns changes. This approach will work for user defined functions as well.
A Gotcha
There will be times when the stored procedure will not appear in the selection in the wizard dialog, that is because of this. Simply add this to the beginning of your stored procedure:
SET FMTONLY OFF -- REMEMBER to remove it once the wizard is done.
public class EmployeeProcedure
{
[Column("EmpId")]
public int EmployeeId { get; set; }
[NotMapped]
public string FullName { get; set; }
public double Salary { get; set; }
}
after that call this:
this.Database.SqlQuery<EmployeeProcedure>("GetAllEmpDetails");

oop asp.net classes for sql server queries

In sql server, I have Students and Departments tables.
I want to get Student records from Student table; with their Department data from Departments table(so i joined them) and show them in an asp.net page.
In asp.net I created a Student class type to use in list in asp.net codebehind.
The list, takes Student class type data like this:
List<Student> lst = new List<Student>();
But I need to get Students with their Department datas. So I created a custom class in asp.net side called StudentsAndDepartments.
Now the list takes this class:
List<StudentsAndDepartments> lst = new List<StudentsAndDepartments>();
My question; do I have to create, for every query I make, an another new custom class?
If I create a custom class for every query I use, there are being too many classes inside the solution.
I think I'm doing wrong..
What should I do?
Thanks for helping..
You do not create a "StudentsAndDepartments" class.
What you are doing here is trying to "flatten out" the domain model, and use one class to represent something that is better defined as a relationship.
You create your domain model. And relate them.
public class Student
{
public string LastName
/* the above is an example 'scalar' property on the Student. you'll have others like FirstName, StudentIdenficationNumber, etc, etc. */
/* below is the 'relationshiop' property, use one of the two below but not both */
public ICollection<Department> Departments;
/* or */
public Department ParentDepartment;
}
public class Department
{
public string DepartmentName
public ICollection<Student> Students;
}
Then you "hydrate" the domain model.
Now this is where things can really vary.
Entity Framework with POCO can do this.
ADO.NET can do this. You write "Serializers" which convert IDataReaders into your object model. This is manual-mapping.
With ADO.NET, you may write different stored procedures...
dbo.uspStudentsGetAllWithParentDepartments
dbo.uspDepartmentsGetAllSimple
dbo.uspDepartmentsGetAllWithChildrenStudents
something like that.
Now, where I digress from others usually.
I do NOT write JOIN SQL statements.
I write 2 separate SQL statements (in ONE stored procedures) to get my data.
dbo.uspStudentsGetAllWithParentDepartments
would like like this
Select st.EmpKey, st.LastName, st.FirstName from dbo.Student st
Select dept.DepartmentKey, dept.DepartmentName from dbo.Department dept where exists (Select null from dbo.Student innerStud where innerStud.ParentDepartmentKey = dept.DepartmentKey )
Now, Entity Framework can do this sql-writing for you, but it is a start-up cost if you've never seen it before.
What my Microsoft-only friends won't mention is that EF does not support the .Merge() function like NHibernate does (another ORM tool). Which is a deal breaker to me. But that's a deeper discussion.
Define your domain-objects, their relationships, and then ask questions about "what's the best way to hydrate my domain-model based on my current skill-sets" (or without the skillset part if you're open to new ways)
Here is a link to another answer I posted...which is the serializer code for the ado.net way of hydrating your objects.
Why is DataTable faster than DataReader

Best practice when storing/retrieving data from database inside class

I would like to know what's the best code design when storing and retrieving data from a database when working with objects and classes.
I could do this in two ways.
In the class constructur I query the database and stores all info in instance variables inside the class and retrieve them with getters/setters. This way I can always get any information I want, but in many cases wont be needing all the information all the time.
public class Group {
public int GroupID { get; private set; }
public string Name { get; private set; }
public Group(int groupID)
{
this.GroupID = groupID;
this.Name = // retrieve data from database
}
public string getName()
{
// this is just an example method, I know I can retrieve the name from the getter :)
return Name;
}
}
The other way is to create some methods and pass in the groupID as a parameter, and then query the database for that specific information I need. This could result in more querys but I will only get the information I need.
public class Group {
public Group()
{
}
public string getName(int groupID)
{
// query database for the name based on groupID
return name;
}
}
What do you think is the best way to go? Is there a best practice to go with here or is it up to me what I think works the best?
You don't want to do heavy DB work in the constructor. Heavy work should be done in methods.
You also don't want to necessarily couple the DB work with the entity class that holds the data. What if you want a method to return two of those objects from the database? For example GetGroups() - you can't even construct one without doing DB work. For something that returns multiple, the storage and retrieval is decouple from the entity class.
Instead, decouple your DB work from your entity objects. One option is you can have a dataaccesslayer with methods like GetFoo or GetFoos etc... that query the database, populate the objects and return them.
If you use an ORM, see:
https://stackoverflow.com/questions/3505/what-are-your-favorite-net-object-relational-mappers-orm
Lazy loading versus early loading, which is what this really boils down to, is best determined by usage.
Mostly this means related entities -- if you are dealing with an individual address for instance, splitting the read for the city from the read for the state would be crazy; OTOH when returning a list of company employee's reading their address information is probably a waste of time and memory.
Also, these aren't mutually exclusive options -- you can have a constructor that calls the databases, and a constructor that uses provided data.
If it is a relational database the best way would be to do it with ORM (object-relational mapping). See here for a list of ORM-mappers:
https://en.wikipedia.org/wiki/List_of_object-relational_mapping_software

Best practices for displaying Foreign Key object names in c# objects

I have a method called GetCustomer that returns a Customer object.
Customer object is as below.
Public class Customer
{
public int Id { get; set;}
public string Name { get; set;}
public int CompanyId { get; set;}
}
Lets say Customer is related to a Company and I have to display this customer information on the screen UI. Now, when I call the GetCustomer method I only get back the details about the Customer. On the screen, I also need to display the companyname that this customer belongs to.
One easy way to do this would be to have a property called CompanyName in the customer object and fill it from your datalayer method. But I'm not sure if thats best practice. If the customer also belongs to a department, now I need to have DepartmentId and DeptName as properties. Ids are a must since sometimes I need to send the Id to get the full Dept/Company object.
I don't want to have the full objects for Department and Company in the Customer object.
I assume this is a common scenario where a particular object is linked to others using an ID and when you bring back the main object, you just need to display the name from the other linked objects.
What is the best to way to handle this. My main intention is to avoid an (or more) extra database call.
I'm NOT using Linq or Entity Framework, just regular ADO.NET.
This situation depends on your goals as;
1 - if you want to avoid extra DB calls, you have to code your UI via your db communicator with only one instance, open it only once and flush its members (adapter, command ..etc.) every time after making DB calls and close connection at the end of data transfers.
2 - for other purpose of your question, use lazy loading. put only id's on your entity and initialize and use the id's belonging entity if needed!
For example:
public class Customer
{
public int Id { get; set;}
public string Name { get; set;}
public int CompanyId { get; set;}
}
public class Company
{
public int CompanyId;
//company fields
}
// .. on your business layer if you need to use Company data:
// examine your Customer instance as "customer"
Company userCompany = GetCompanyWithId(customer.CompanyId);
but as you no doubt of your guess, data that is going to load is depends of your needs. Think simple. If your only need is Department and Company names, than you can create a view on your DB and can call it on your code. You can create an entity as CustomerWithFullData and you can put a Customer and a Department etc. in this entity and when you need to show full data you can fill this with DB View. Or dont bother to create entities. If you dont need entity, Call DB View directly DataSet and bind Tables. So you can transfer data collection work to DB and this is what we want to do.
As i said before, think simple.
What I would do is to retain an OO structure at the level of your business objects, and modify your DAL to return all the information you need with a single DB round-trip.
For example, you could have a stored procedure that returns two result sets: one for the Customers, and another for the Companies they reference. You could use table valued parameters to pass the SP a list of one or more Customers to look-up.
Depending on the size of your DB and your performance requirements, you also might be able to read the entire Customer and Company tables into memory when the app starts, cache the results, and manage insert/update/deletes against that data.

Store objects with common base class in database

Let's say i have a common base class/interface
interface ICommand
{
void Execute();
}
Then there are a few commands inheriting from this interface.
class CommandA : ICommand
{
int x;
int y;
public CommandA(int x, int y)
{ ... }
public void Execute () { ... }
}
class CommandB : ICommand
{
string name;
public CommandB(string name)
{ ... }
public void Execute () { ... }
}
Now i want to store these commands in a database, with a common method, and then later load all of them from the DB into a List<ICommand> and execute the Execute-method of them.
Right now I just have one table in the DB called commands and here i store a string serialization of the object. Basically the columns in the table are: id|commandType|commaSeparatedListOfParameters. While this is very easy and works good for loading all commands, I can't query the commands easily without using substring and other obscure methods. I would like to have an easy way of SELECT id,x,y FROM commandA_commands WHERE x=... and at the same time have a generic way of loading all commands from the commands-table (i guess this would be some kind of UNION/JOIN of commandA_commands, commandB_commands, etc).
It is important that not much manual fiddling in the DB, or manual creation of serialize/parse-methods, is required to add a new command. I have tons of them and new ones are added and removed all the time. I don't mind creating a command+table+query generation tool though if this would be required for the best solution.
The best i can think of myself is a common table like id|commandType|param1|param2|param3|etc.. which isn't much better (actually worse?) than my current solution as many commands are going to need null parameters and the datatype will vary so i have to resort to common string conversion again and size each field big enough for the largest command.
The database is SQL Server 2008
Edit: Found similar question here Designing SQL database to represent OO class hierarchy
You can use an ORM to map the command inheritance to database. For example you can use "Table per Hierarchy" technique provided by the ORMs (eg: Entity Framework, nHibernate, etc). ORM will instantiate the correct subclass when you retrieve them.
Here's an example of doing it in Entity Framework Code first
abstract class Command : ICommand
{
public int Id {get;set;}
public abstract void Execute();
}
class CommandA : Command
{
public int X {get;set;}
public int Y {get;set;}
public override void Execute () { ... }
}
class CommandB : Command
{
public string Name {get;set;}
public override void Execute () { ... }
}
Refere EF 4.1 Code First Walkthrough to configure this model with EF.
If your commands takes drastically different set of parameter you can consider using "Table per Type" inheritance modeling. Here you will have pay some significant performance penalty because of lot of Unions and table joins involved in this.
Alternative approach would be to store the Command parameters as a XML configuration where you (de)serialize manually. This way you can keep all your commands in a single table without sacrificing performance. Again this has a drawback where you can not filter using the command parameters.
Each approach has its Pros and Cons. You can choose the strategy which suits your requirements.
This problem is pretty common, and I haven't seen a solution that is without drawbacks. The only option to exactly store a hierarchy of objects in a database is to use some NoSQL database.
However, if a relational database is mandated, I usually go with this approach:
one table for the base class/interface, that stores the common data for all types
one table per descending class, that uses the exact same primary key from the base table (this is a nice use case for the SQL Server 2011 sequences, btw)
one table that holds the types that will be stored
a view that joins all those tables together, to enable easy loading/querying of the objects
In your case, I would create:
Table CommandBase
ID (int or guid) - the ID of the command
TypeID (int) - ID of the type of command
Table CommandA
ID (int or guid) - the same ID from the CommandBase table
X (int)
Y (int)
Table CommandB
ID (int or guid) - the same ID from the CommandBase table
Name (nvarchar)
Table CommandTypes
ID (int) - ID of the command type
Name (nvarchar) - Name of the command type ("CommandA", "CommandB",...)
TableName (nvarchar) - Name of the table that stores the type - usefull if some dynamic sql is needed - otherwise optional
View Commands, something along the lines of:
select cb.ID, a.X, a.Y, b.Name
from CommandBase cb
left outer join CommandA a on a.ID = cb.ID
left outer join CommandB b on b.ID = cb.ID
The upside of this approach is that it mirrors your class structure. It's easy to understand and use.
The downside is that is gets more and more cumbersome as you add new classes, it's hard to model more then one level of hierarchy, and the view can get a mile long if there are lots of descendants.
Personally, I would use this approach if I know that the number of subclasses is relatively small and relatively fixed, as it requires creating (and maintaining) a new table for each new type. However, the model is quite simple, so it's possible to create a tool/script that could do the creating and maintaining for you.
We are using XML in SQL more and more for our soft data. It might be slightly painful to query (using XPath), but it allows us to store metadata per row, validated against a schema, etc.
XML can then be parsed by code and parameters can be matched via reflection to parameters in the de-serialised object.
Effectively this replicates the ORM functionality, but with a flat database structure, simplifies queries, and the parameters are even queryable through XPath.
And remember kids, views are evil.

Categories

Resources