So here is the scenario: i have a series of different repository classes that each can use an isolated data context, or a shared context. In the cases where an isolated context is being used i want to add a method to the base class that will allow me to specify the lambda as the parameter, have that expression be executed by the isolated context of the chosen repository and return an IQueryable result. How would the method signature look, and how to a pass the expression to the context?
I need the solution to be as generic as possible as any possible model object/table could be used.
Here is basically what i am looking to do:
IAssetRepository repo = new AssetRepository(true); // true indicates isolated context
var results = repo.ExecuteInContext<SomeType>(SomeTable.Where(x =>
x.SomeProp.Equals(SomeValue)));
Using delegates you can pass a lambda expression as a parameter to a function, and then use it in LINQ queries. This can be done with Func<…> delegates. If you want to pass a lambda expression to be used, for example, in Where clause, you need a Func<T, bool> delegate.
The => operator can be used in two ways in C#: As the lambda operator in a lambda expression, it separates the input variables from the lambda body. In an expression body definition, it separates a member name from the member implementation.
Advertisements. The term 'Lambda expression' has derived its name from 'lambda' calculus which in turn is a mathematical notation applied for defining functions. Lambda expressions as a LINQ equation's executable part translate logic in a way at run time so it can pass on to the data source conveniently.
So performance-wise, there's no difference whatsoever between the two. Which one you should use is mostly personal preference, many people prefer lambda expressions because they're shorter and more concise, but personally I prefer the query syntax having worked extensively with SQL.
Something like this:
public IEnumerable<T> ExecuteInContext<T>(
Expression<Func<T,bool>> predicate)
{
... // do your stuff
//eg
Table<T> t = GetTable<T>();
return t.Where(predicate);
}
or
public IEnumerable<T> ExecuteInContext<T>(
IQueryable<T> src, Expression<Func<T,bool>> predicate)
{
return src.Where(predicate);
}
Usage:
var r = repo.ExecuteInContext<SomeType>(
x => x.SomeProp.Equals(Somevalue));
or
var r = repo.ExecuteInContext(GetTable<T>(),
x => x.SomeProp.Equals(Somevalue));
Assumptions:
Here is a complete working sample how to pass LINQ expression as a parameter
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleTest
{
public class Values
{
public int X { get; set; }
public int Y { get; set; }
public override string ToString()
{
return String.Format("[ X={0} Y={1} ]", X, Y);
}
}
class Program
{
static void Main()
{
var values = new Values {X = 1, Y = 1};
// pass parameter to be incremented as linq expression
IncrementValue(values, v => v.X);
IncrementValue(values, v => v.X);
IncrementValue(values, v => v.Y);
// Output is: [ X=3 Y=2 ]
Console.Write(values);
}
private static void IncrementValue<T>(T obj, Expression<Func<T,int>> property)
{
var memberExpression = (MemberExpression)property.Body;
var propertyInfo = (PropertyInfo)memberExpression.Member;
// read value with reflection
var value = (int)propertyInfo.GetValue(obj, null);
// set value with reflection
propertyInfo.SetValue(obj, ++value, null);
}
}
}
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