I want to create a complex type to use within an entity manager from a query constructed dynamically and executed with exec()
. Is it possible?; since I'm writing a filter, what would you do instead if it is not possible?
Also, I'm evaluating using linq, but the filter needs many tables and their registers, therefore efficiency is a concern.
Thanks...
On the designer surface, select one or more properties (excluding navigation properties) of an entity, then right-click and select Refactor -> Move to New Complex Type. A new complex type with the selected properties is added to the Model Browser. The complex type is given a default name.
Each procedure has one or more statements. In our case, these are SQL statements. So, you can write a procedure that will – insert new data, update or delete existing, retrieve data using the SELECT statement. And even better, you can combine more (different statements) in the stored procedures.
Stored procedures are faster as compared to LINQ query since they have a predictable execution plan and can take the full advantage of SQL features. Hence, when a stored procedure is being executed next time, the database used the cached execution plan to execute that stored procedure.
Yes, you can use Entity Framework 4 and LINQ on top, it generates the parametrized query and executes it, that's the option.
Another option is (and I did several times) to create a base class/interface, let's say:
public interface IExecutable
{
void Execute(IConnection connection);
}
public interface IExecutable<TResult> : IExecutable
{
TResult Result { get; }
}
public abstract ActionBase<TResult> : IExecutable<TResult>
{
protected void AddParameter(....);
protected IDataReader ExecuteAsReader(string query) {
//create a DB Command, open transaction if needed, execute query, return a reader.
}
protected object ExecuteAsScalar(string query) {
//....
}
//the concrete implementation
protected abstract TResult ExecuteInternal();
IExecutable.Execute(IConnection connection) {
//keep the connection
this.Result = ExecuteInternal();
}
//another common logic:
}
Then you can create your concrete actions:
public sealed class GetUsersAction : ActionBase<<IList<User>>
{
//just a constructor, you provide it with all the information it neads
//to be able to generate a correct SQL for this specific situation
public GetUsersAction(int departmentId) {
AddParameter("@depId", departmentId);
}
protected override IList<User> ExecuteInternal() {
var command = GenerateYourSqlCommand();
using(var reader = ExecuteAsReader(command)) {
while(reader.Read) {
//create your users from reader
}
}
//return users you have created
}
}
Very easy to create concrete actions!
Then, to make it even easier, create an ExecutionManager whose concern is how to get the connection and execute the action:
public sealed ExecutionManager() {
TResult Execute<TResult>(IExecutable<TResult> action) {
var connection = OhOnlyIKnowHowTOGetTheConnectionAnfHereItIs();
action.Execute(connection);
return action.Result;
}
}
Now just use it:
var getUsersAction = new GetUsersAction(salesDepartmentId);
//it is not necessary to be a singletone, up to you
var users = ExecutionManager.Instance.Execute(getUsersAction);
//OR, if you think it is not up to ExecutionManager to know about the results:
ExecutionManager.Instance.Execute(getUsersAction);
var users = getUsersAction.Result
Using this simple technique it is really easy to move all the connection/command/execution logic away from the concrete actions into the base class, and the concrete actions' concerns are just generating SQLs and converting database output into some meaningful results.
Good luck :)
If you decide to go the Linq route and are looking for a good way to do filtering. LinqKit is a great library for building ad-hoc predicates. The problem with the built-in linq library is that you can only ad-hoc combine AND statements, you can not ad-hoc combine OR statements. Linqkit makes that a breeze to accomplish.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With