I need to translate this simple SQL query into LINQ using EF entities:
SELECT * FROM Clientes WHERE ID_Cliente IN(SELECT ID_Objeto FROM
Direcciones where ID_TipoDireccion=IDTipoDireccion)
Seems very simple, but it seems to be a very hard to achieve. I try this:
public List<Clientes> EnumEntity(int IDTipoDireccion)
{
var dir = new DireccionesRepository(ref rep.Context);
var misClientes = rep.ListEntity();
var misDirColection = dir.ListEntity().ToList().Where(o => o.ID_TipoDireccion == IDTipoDireccion);
foreach (var item in misDirColection)
{
misClientes=misClientes.Where(p => p.ID_Cliente == item.ID_Objeto);
}
return misClientes.ToList();
}
The problem with above query is that use AND. I need it to use OR to include all clients that matches Direcciones object.
I try PredicateBuilder class but it doesn't support EF. I found this adaptation of PredicateBuilder that seems to resolve this problem:
internal class SubstExpressionVisitor : System.Linq.Expressions.ExpressionVisitor
{
public Dictionary<Expression, Expression> subst = new Dictionary<Expression, Expression>();
protected override Expression VisitParameter(ParameterExpression node)
{
Expression newValue;
if (subst.TryGetValue(node, out newValue))
{
return newValue;
}
return node;
}
}
public static class PredicateBuilder
{
/*public static Expression<Func<T,bool>> True<T>() { return f => true; }*/
//public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
{
ParameterExpression p = a.Parameters[0];
SubstExpressionVisitor visitor = new SubstExpressionVisitor();
visitor.subst[b.Parameters[0]] = p;
Expression body = Expression.AndAlso(a.Body, visitor.Visit(b.Body));
return Expression.Lambda<Func<T, bool>>(body, p);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
{
ParameterExpression p = a.Parameters[0];
SubstExpressionVisitor visitor = new SubstExpressionVisitor();
visitor.subst[b.Parameters[0]] = p;
Expression body = Expression.OrElse(a.Body, visitor.Visit(b.Body));
return Expression.Lambda<Func<T, bool>>(body, p);
}
}
But the problem is I don't know how to use it in my case.
Can anybody help me?
Thanks!
EDIT
After adapting the suggested code, this is the result in case someone else need it:
public List<EnumeradorWCFModel> EnumEntity(int IDTipoDireccion)
{
// SELECT * FROM Clientes WHERE ID_Cliente IN(SELECT ID_Objeto FROM Direcciones where ID_TipoDireccion=IDTipoDireccion)
// Get All directions of type IDTipoDireccion
var dir = new DireccionesRepository(ref rep.Context);
var misDirColection = dir.ListEntity().Where(x => x.ID_TipoDireccion == IDTipoDireccion)
.Select(x => x.ID_Objeto); // Do not iterate!
// Itinerate Clients
var misClientes = rep.ListEntity().Where(x => misDirColection.Contains(x.ID_Cliente)).ToList();
return misClientes.ToList();
}
Use Contains().
SELECT * FROM Clientes WHERE ID_Cliente IN(SELECT ID_Objeto FROM Direcciones where ID_TipoDireccion=IDTipoDireccion)
Can be directly translated to:
int IDTipoDireccion = ...
// First, create a query for your subselect.
var direcciones = dbContext.Direcciones
.Where(x => x.ID_TipoDireccion == IDTipoDireccion);
.Select(x => x.ID_Objeto); // Do not iterate!
// Then, use the first query in the WHERE of your second query.
var results = dbContext.Clientes
.Where(x => direcciones.Contains(x.ID_Cliente))
.ToList();
Related
I have filters in my asp.net project and want to add expression to this list with condition:
Expression<Func<MyModel, bool>> func;
var list = new List<Expression<Func<MyModel, bool>>>();
I want to conditionally apply Where (OR between them). for example:
if(sth){
func = p => p.a <= b;
list.Add(func);
}
if (sth else){
func = p => p.c >= d;
list.Add(func);
}
var fq = Session.Query<MyModel>();
fq = list.Aggregate(fq, (current, expression) => current.Where(expression));
How can I do this?
You can build an extension method to merge two condition expressions using OR relationship like this:
public static class Extensions
{
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> one, Expression<Func<T, bool>> another)
{
var parameter = one.Parameters[0];
var visitor = new ReplaceParameterVisitor(parameter);
another = (Expression<Func<T, bool>>)visitor.Visit(another);
var body = Expression.Or(one.Body, another.Body);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
}
class ReplaceParameterVisitor : ExpressionVisitor
{
public ParameterExpression NewParameter { get; private set; }
public ReplaceParameterVisitor(ParameterExpression newParameter)
{
this.NewParameter = newParameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return this.NewParameter;
}
}
Usage and test code:
Expression<Func<int, bool>> condition1 = x => x > 8;
Expression<Func<int, bool>> condition2 = y => y < 3;
var condition = condition1.Or(condition2);
var result = Enumerable
.Range(1, 10)
.Where(condition.Compile())
.ToList(); //1,2,9,10
Looks like you could do this easily with an extension method
public static class EnumerableExtensions
{
public static IEnumerable<T> ConditionalWhere<T>(this IEnumerable<T> list,
bool condition, Func<T,bool> predicate)
{
if(!condition)
return list;
return list.Where(predicate);
}
}
Usage would be:
var fq = Session.Query<MyModel>();
var result = fq.ConditionalWhere(sth, p => p.a <= b)
.ConditionalWhere(sth_else, p => p.c >= d);
I built a bit of code to showcase Predicate<> while trying to stick to your program structure:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SOTests
{
public class MyModel
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
private static int ControlId;
private static string ControlName;
static void Main(string[] args)
{
var idPred = new Predicate<MyModel>(m => m.Id > ControlId);
var namePred = new Predicate<MyModel>(m => m.Name == ControlName);
var list = new List<MyModel>();
if (true) // TODO: do id check?
{
list = list.Where(m => idPred.Invoke(m)).ToList();
}
if (true) // TODO: do name check?
{
list = list.Where(m => namePred.Invoke(m)).ToList();
}
//var fq = Session.Query<MyModel>();
//fq = list;
}
}
}
I commented out the Session bit not knowing what kind of storage abstraction it represents (and the code wouldn't compile).
The code should explain itself and it's not tested.
It can be much more elegant, but you should state more clearly what your requirements are for that.
Thanks all, I found the solution : OrElse
Expression<Func<MyModel, bool>> OrExpressionFunction(Expression<Func<MyModel, bool>> exp1, Expression<Func<MyModel, bool>> exp2)
{
ParameterExpression p = exp1.Parameters.Single();
return Expression.Lambda<Func<MyModel, bool>>(
Expression.OrElse(exp1.Body, exp2.Body), p);
}
then:
Expression<Func<MyModel, bool>> MyExp = null;
if(sth){
func = p => p.a <= b;
MyExp= OrExpressionFunction(func, MyExp);
}
if (sth else){
func = p => p.c >= d;
MyExp= OrExpressionFunction(func, MyExp);
}
list.Add(MyExp);
I have a C# LINQ query that has a main query and then 2 other queries depending on if a variable is not set 0.
The query is working, but I need to combine the resultsets and return that.
I want the final resultset to contain the results of the two subqueries combined. Kind of like in a SQL query where you have:
SELECT * FROM myTable WHERE column1 = 'abc' OR column2 = 'xyz'
Right now, I think it's using an AND instead of an OR
var GeoLocations = rows.Select(r => new ElementSearchGeoLocation(r))
.Where(t => (t.GeoLocationType == "State" && t.CanViewState(t.GeoLocationState, user)) ||
(t.GeoLocationType == "City" && t.CanViewCity(t.GeoLocationCity, user)));
if(SystemList != 0)
{
GeoLocations = GeoLocations.Where(t => (dto.SystemList.Contains(t.SystemID)));
}
if (groupList != 0)
{
GeoLocations = GeoLocations.Where(t => (dto.groupList.Contains(t.PoliticalID)));
}
return Ok(GeoLocations);
Is there a way to do this in LINQ?
Here is an implementation of a PredicateBuilder that is able to Or together two different expressions:
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var secondBody = expr2.Body.Replace(
expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var secondBody = expr2.Body.Replace(
expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
}
}
It's dependant on the following code to be able to replace all instances of one expression with another:
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
internal static class ExpressionExtensions
{
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
}
Using this you can now write:
var GeoLocations = rows.Select(r => new ElementSearchGeoLocation(r))
.Where(t => (t.GeoLocationType == "State" && t.CanViewState(t.GeoLocationState, user)) ||
(t.GeoLocationType == "City" && t.CanViewCity(t.GeoLocationCity, user)));
var predicate = PredicateBuilder.False();
if(SystemList != 0)
{
predicate = predicate.Or(t => dto.SystemList.Contains(t.SystemID));
}
if (groupList != 0)
{
predicate = predicate.Or(t => dto.groupList.Contains(t.PoliticalID));
}
return Ok(GeoLocations.Where(predicate));
Use Concat to add in the additional rows. To make the code super minimal, I would store off the initial `Select first:
var AllLocations = rows.Select(r => new ElementSearchGeoLocation(r));
var mainQuery = AllLocations.Where(t => (t.GeoLocationType == "State" && t.CanViewState(t.GeoLocationState, user)) ||
(t.GeoLocationType == "City" && t.CanViewCity(t.GeoLocationCity, user)));
Then:
IEnumerable<GeoLocation> subQuery;
if (SystemList != 0)
subQuery = AllLocations.Where(...);
else
subQuery = AllLocations.Where(...);
var GeoLocations = mainQuery.Concat(subQuery);
If you care about duplicates, you can use Union instead of Concat for the last step.
Two methods come up for this behaviour
Union, which combines two result sets while culling for duplicates
Concat, which simply slams two result sets together
Which one you choose depends on desired behaviour. Note that either of these may or may not work if your queries are actually IQueryables and running from a database (via linq-to-sql or Entity Framework or the like).
As has been mentioned, do not forget that LINQ results are lazily-evaluated, and this parts of a query can be safely saved and rehashed for later.
I've looked into many generic linq filtering questions and their answers here in SO but none of them satisfy my needs so I thought I should create a question.
I've created many of what I call "filter provider" classes, one for each entity class in my model, to provide a simplistic search for my application. I didn't want to go into more advanced solutions like Lucene.Net because a basic filtering with matching score would suffice.
Inside each one of these provider classes there are multiple methods that will receive the filtering terms and query specific properties, returning a score for each match based on the relevance of the property. Most methods will filter multiple properties at once, but not all.
Here are two of these methods:
private IQueryable<Retailer> MatchHighRelevanceFields(string searchTerm, IQueryable<Retailer> retailers)
{
var results = retailers.Where(r =>
(r.CompanyName != null && r.CompanyName.ToUpper().Contains(searchTerm))
|| (r.TradingName != null && r.TradingName.ToUpper().Contains(searchTerm))
);
return results;
}
private IQueryable<Retailer> MatchMediumRelevanceFields(string searchTerm, IQueryable<Retailer> retailers)
{
var results = retailers.Where(r =>
(r.Address.Street != null && r.Address.Street.ToUpper().Contains(searchTerm))
|| (r.Address.Complement != null && r.Address.Complement.ToUpper().Contains(searchTerm))
);
return results;
}
These methods are replicated ad nauseum throughout each provider class and I hope I could replace them for a single method that would receive the properties to be included in the query.
Something like:
public static IQueryable<T> Match<T>(string searchTerm, IQueryable<T> data, Expression<Func<T, string>> filterProperties)
{
var results = **build the query for each property in filterProperties**
return results;
}
But I really can't figure it out. I tried using reflection but it only worked with Linq to Objects and I need a solution for Linq to Entities.
So to solve this problem we need a few puzzle pieces first. The first puzzle piece is a method that can take an expression that computes a value, and then another expression that computes a new value taking the same type the first returns, and creates a new expression that represents the result of passing the result of the first function as the parameter to the second. This allows us to Compose expressions:
public static Expression<Func<TFirstParam, TResult>>
Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first,
Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
This relies on the following tool to replace all instances of one expression with another:
public static Expression Replace(this Expression expression,
Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
We'll also need a tool to help us OR two predicate expressions together:
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var secondBody = expr2.Body.Replace(
expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, secondBody), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(
this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var secondBody = expr2.Body.Replace(
expr2.Parameters[0], expr1.Parameters[0]);
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters);
}
}
Now that we have this we can use Compose on each property selector to map it from the property results to whether or not that property value is non-null and contains the search term. We can then OR all of those predicates together to get a filter for your query:
public static IQueryable<T> Match<T>(
IQueryable<T> data,
string searchTerm,
IEnumerable<Expression<Func<T, string>>> filterProperties)
{
var predicates = filterProperties.Select(selector =>
selector.Compose(value =>
value != null && value.Contains(searchTerm)));
var filter = predicates.Aggregate(
PredicateBuilder.False<T>(),
(aggregate, next) => aggregate.Or(next));
return data.Where(filter);
}
You can do it with expression trees but it's not as simple as you might think.
public static IQueryable<T> Match<T>(this IQueryable<T> data, string searchTerm,
params Expression<Func<T, string>>[] filterProperties)
{
var parameter = Expression.Parameter(typeof (T), "source");
Expression body = null;
foreach (var prop in filterProperties)
{
// need to replace all the expressions with the one parameter (gist taken from Colin Meek blog see link on top of class)
//prop.body should be the member expression
var propValue =
prop.Body.ReplaceParameters(new Dictionary<ParameterExpression, ParameterExpression>()
{
{prop.Parameters[0], parameter}
});
// is null check
var isNull = Expression.NotEqual(propValue, Expression.Constant(null, typeof(string)));
// create a tuple so EF will parameterize the sql call
var searchTuple = Tuple.Create(searchTerm);
var matchTerm = Expression.Property(Expression.Constant(searchTuple), "Item1");
// call ToUpper
var toUpper = Expression.Call(propValue, "ToUpper", null);
// Call contains on the ToUpper
var contains = Expression.Call(toUpper, "Contains", null, matchTerm);
// And not null and contains
var and = Expression.AndAlso(isNull, contains);
// or in any additional properties
body = body == null ? and : Expression.OrElse(body, and);
}
if (body != null)
{
var where = Expression.Call(typeof (Queryable), "Where", new[] {typeof (T)}, data.Expression,
Expression.Lambda<Func<T, bool>>(body, parameter));
return data.Provider.CreateQuery<T>(where);
}
return data;
}
public static Expression ReplaceParameters(this Expression exp, IDictionary<ParameterExpression, ParameterExpression> map)
{
return new ParameterRebinder(map).Visit(exp);
}
Now you need to have a expressionvisitor to make all the expressions use one parameter
//http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx
public class ParameterRebinder : ExpressionVisitor
{
private readonly IDictionary<ParameterExpression, ParameterExpression> _map;
public ParameterRebinder(IDictionary<ParameterExpression, ParameterExpression> map)
{
_map = map;
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (_map.ContainsKey(node))
{
return _map[node];
}
return base.VisitParameter(node);
}
}
Would use it like
var matches = retailers.Match("7", r => r.Address.Street, x => x.Address.Complement).ToList();
Warning - I checked this with linq to objects using the AsQueryable but didn't run it against EF.
You can use Linq.Dynamic to build the query.
public static IQueryable<T> Match<T>(
string searchTerm,
IQueryable<T> data,
params Expression<Func<T, string>>[] filterProperties) where T : class
{
var predicates = new List<string>();
foreach (var prop in filterProperties)
{
var lambda = prop.ToString();
var columnName = lambda.Substring(lambda.IndexOf('.') + 1);
var predicate = string.Format(
"({0} != null && {0}.ToUpper().Contains(#0))", columnName);
predicates.Add(predicate);
}
var filter = string.Join("||", predicates);
var results = data.Where(filter, searchTerm);
return results;
}
Usage.
var retailers = Match(
"asd", db.Retailers, r => r.CompanyName, r => r.TradingName);
var retailers = Match(
"asd", db.Retailers, r => r.Address.Street, r => r.Address.Complement);
Limitation.
The filter can only accept basic expression.
r => r.Name
r => r.PropA.Name
r => r.PropA.PropB.Name
Try to use Expressions like those all
http://www.codeproject.com/Articles/493917/Dynamic-Querying-with-LINQ-to-Entities-and-Express
I have a dbml context query that looks something like this:
var SQLQueryResult = (from activeTable in context.activeTabless
where (
activeTable .AssignedTo == "Person1" ||
activeTable .AssignedTo == "Person2" ||
activeTable .AssignedTo == "Person3")
select new { ... });
My question is, how can I update the where field so that it can have any number of or (not just three as above) based on a user selection?
Let's say the number can come from a list or array.
That's simple with straight SQL but not sure how to do it via Linq to SQL.
var persons = new []{"Person1", "Person2", "Person3"};
var SQLQueryResult = (from activeTable in context.activeTabless
where ( persons.Contains(activeTable .AssignedTo))
select new { ... });
You can check if something exists in a collection using the .Contains() extension method of IEnumerable.
You can create your query dynamically by using Expressions for being able to build where predicates. More details and a sample you can find here: Linq dynamic queries
You can use predicate builder (utility class):
using System;
using System.Linq;
using System.Linq.Expressions;
public static class PredicateBuilder {
public static Expression<Func<T, bool>> Make<T>() {
return null;
}
public static Expression<Func<T, bool>> Make<T>(this Expression<Func<T, bool>> predicate) {
return predicate;
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr, Expression<Func<T, bool>> orExpression) {
if (expr == null) {
return orExpression;
}
var invokedExpr = Expression.Invoke(orExpression, expr.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.Or(expr.Body, invokedExpr), expr.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr, Expression<Func<T, bool>> andExpression) {
if (expr == null) {
return andExpression;
}
var invokedExpr = Expression.Invoke(andExpression, expr.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.And(expr.Body, invokedExpr), expr.Parameters);
}
}
Usage:
public IEnumerable<Squad> GetSquadsByIDs(IEnumerable<int> squadIDs) {
if (squadIDs == null || !squadIDs.Any()) {
throw new ArgumentNullException("squadIDs");
}
var condition = PredicateBuilder.Make<Squad>(s => false);
foreach (var squadID in squadIDs) {
int squadIDValue = squadID;
condition = PredicateBuilder.Or<Squad>(condition, s => s.SquadID == squadIDValue);
}
var db = m_DalContextProvider.GetContext();
return db.Squads.Where(condition);
}
I have an entity class like
public class BookPage {
public int PageIndex { get; set; }
}
then I have an expression:
Expression<Func<int, bool>> pageIndexCondition = idx => idx == 1;
and the expression I want:
Expression<Func<BookPage, bool>> pageCondition = bookPage => bookPage.PageIndex == 1;
The question: How do I use pageIndexCondition to do LINQ-to-SQL query, or how can I convert pageIndexCondition into pageCondition?
Edit: Another solution that would be less elegant, but still meet my requirement is:
Expression<Func<T, bool>> GetPageIndexCondition(Expression<Func<T, int>> selector) {
return (T item) => selector(item) < 10; // This won't work because selector is Expression, so how to implement this correctly?
}
...
var pageCondition = GetPageIndexCondition(page => page.PageIndex);
I like doing these things, though as others have said, there's probably more efficient and better ways to do it:
void Main()
{
Expression<Func<int, bool>> pageIndexCondition = idx => idx == 1;
Expression<Func<BookPage, bool>> converted = ExpressionConverter.Convert(pageIndexCondition);
}
public class ExpressionConverter : ExpressionVisitor
{
public static Expression<Func<BookPage, bool>> Convert(Expression<Func<int, bool>> e)
{
var oldParameter = e.Parameters.First();
var newParameter = Expression.Parameter(typeof(BookPage), "bp");
Expression<Func<BookPage, int>> x = (BookPage bp) => bp.PageIndex;
var property = ((x.Body as MemberExpression).Member as PropertyInfo);
var memberAccess = Expression.Property(newParameter, property);
var converter = new ExpressionConverter(oldParameter, memberAccess);
return (Expression<Func<BookPage, bool>>)Expression.Lambda(converter.Visit(e.Body), newParameter);
}
private ParameterExpression pe;
private Expression replacement;
public ExpressionConverter(ParameterExpression pe, Expression replacement)
{
this.pe = pe;
this.replacement = replacement;
}
protected override Expression VisitParameter(ParameterExpression node)
{
if(node == pe)
return replacement;
return base.VisitParameter(node);
}
}
var pages = new List<BookPage>
{
new BookPage { PageIndex = 1 },
new BookPage { PageIndex = 2 }
};
Expression<Func<BookPage, bool>> pageCondition = bookPage => bookPage.PageIndex == 1;
BookPage result = pages.AsQueryable().Single(pageCondition);
If you want a generic select by id you will have to do something like;
public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null)
{
if (filter != null)
{
query = query.Where(filter);
}
}
This goes in your generic repository.