I need one help to solve my mock related question in .net, I have one function with below code.
Task<ICollection<T>> GetAllAsync(Expression<Func<T, bool>> predicate, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, Func<IQueryable<T>, IQueryable<T>> includes = null);
Where we have a T as class, now I want to use the below code for the mocking.
var predict = PredicateBuilder.True<cls1>();
if (DropdownRequestVM?.AllParent == false)
{
predict = predict.And(x => x.Parentid == DropdownRequestVM.ParentID);
}
else
{
predict = predict.And(x => x.Parentid == null);
}
var returneddata = data.AsQueryable().Where(predict).ToList();
this.mockservice
.Setup(repo => repo.Repository
.GetAllAsync(It.IsAny<Expression<Func< cls1, bool>>>(),
It.IsAny<Func<IQueryable< cls1>, IOrderedQueryable< cls1>>>(),
It.IsAny<Func<IQueryable< cls1>, IQueryable< cls1>>>()))
.Returns(Task.FromResult<ICollection< cls1>>(returneddata));
Now my query is. I do not want to use the It.isany, as its allow all the expression, so that I have passed predict, but even I have setup the methods. Its returning the null. I have setup the method below way.
this.mockservice
.Setup(repo => repo.Repository
.GetAllAsync(predict,
It.IsAny<Func<IQueryable< cls1>, IOrderedQueryable< cls1>>>(),
It.IsAny<Func<IQueryable< cls1>, IQueryable< cls1>>>()))
.Returns(Task.FromResult<ICollection< cls1>>(returneddata));
You could try something like, not 100% sure about the syntax
this.mockservice
.Setup(repo => repo.Repository
.GetAllAsync(It.Is<Expression<Func<cls1,bool>>>(x => LambdaCompare.Eq(x,predict)),It.IsAny<Func<IQueryable<cls1>, IOrderedQueryable<cls1>>>(),It.IsAny<Func<IQueryable<cls1>, IQueryable<cls1>>>()))
.Returns(Task.FromResult<ICollection< cls1>>(returneddata));
Related
I'm trying to moq a repository I have which is defined as:
public IQueryable<TEntity> GetAll(Expression<Func<TEntity, bool>> predicate = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null, bool disableTracking = true)
Is there a way to mock this? I want the query to execute, using the mock data i supply the repos. I'm not sure how to tell MOQ that when I call GetAll I want it to still run the query that is passed in, but do it aganist the dataset I supply. so it's not going to the db but against the mock set which I've configured. I'm able to create the data, it contain 12 records, but I want the getall moq call to execute it's query and filter it to just the 2 that should be returned.
The actual service where the call happens is:
var list = await _unitOfWork.GetRepository<CASE_ACTIVITY>().GetAll(predicate: x => x.SM_SITE_ID == siteId && x.CMS_USER_ID == userId
&& x.IS_DELETED == "N" && x.Appointment.IS_DELETED == "N" && x.Appointment.IS_ARCHIVED == "N" && x.IS_ARCHIVED == "N"
&& ((x.Appointment.APPOINTMENT_DATETIME.HasValue && x.Appointment.APPOINTMENT_DATETIME.Value.Date == DateTime.Today.Date)
|| (!x.Appointment.APPOINTMENT_DATETIME.HasValue && x.ACTIVITY_STATUS_ID == _appSettings.CASE_ACTIVITY_STATUS_ID_PENDING)))
.Include(x => x.Activity_Lookup).Include(x => x.Appointment).ThenInclude(x => x.Cms_Client).Include(x => x.Cms_Case)
.ToListAsync();
Assuming you have enough control over the GetRepository() method to make it return your mock repository, mocking the method itself is fairly straightforward (if a little verbose). I just dumped the GetAll method into an interface called IRepository, and this is what the mock looks like. Inside of the Returns method, you have access to each of the parameters to execute or ignore as you please.
var mock = new Moq.Mock<IRepository>();
mock.Setup(a => a.GetAll<int>(It.IsAny<Expression<Func<int, bool>>>(), It.IsAny<Func<IQueryable<int>, IOrderedQueryable<int>>>(), It.IsAny<Func<IQueryable<int>, IIncludableQueryable<int, object>>>(), It.IsAny<bool>()))
.Returns<Expression<Func<int, bool>>, Func<IQueryable<int>, IOrderedQueryable<int>>, Func<IQueryable<int>, IIncludableQueryable<int, object>>, bool>((param1, param2, param3, param4) =>
{
return new[] { 1, 2, 3 }.AsQueryable();
});
var result = mock.Object.GetAll<int>();
From here, we can't help much without seeing more code. In abstract terms, though, you'll take your mock.Object (which is of type IRepository) and feed it to whatever collection GetRepository() draws from. Also note, of course, that I used an int for the generic parameter -- you'll replace that with whatever type you're using. It may be possible to make a mock that accepts generic parameters, but that hopefully won't be necessary!
I often come across, in LINQ for Entity Framework, a pattern where I add a .Where clause if a string value is specified, like:
IQueryable<Foo> query = Foos.AsQueryable()
if (!string.IsNullOrWhitespace(nameFilter)) query = query.Where(x => x.Name == name);
if (!string.IsNullOrWhitespace(addressFilter) != null) query = query.Where(x => x.Address == addressFilter );
if (!string.IsNullOrWhitespace(cityFilter) != null) query = query.Where(x => x.City == cityFilter );
// ...
I wanted to clean this up and avoid repeating the filter. I thought I could create an extension method:
public static IQueryable<T> WhereEqualIfSpecified<T>(
this IQueryable<T> query,
Expression<Func<T, string>> fieldDelegate,
string filterValue)
{
return string.IsNullOrWhiteSpace(filterValue)
? query
: query.Where(x => fieldDelegate(x) == filterValue); // not valid, see question below
}
So that I can instead change my code to:
IQueryable<Foo> query = Foos.AsQueryable()
.WhereEqualIfSpecified(x => x.Name, nameFilter)
.WhereEqualIfSpecified(x => x.Address, addressFilter)
.WhereEqualIfSpecified(x => x.City, cityFilter)
// ...
;
But I found that, in the WhereEqualIfSpecified method above, fieldDelegate must be compiled to a Func() to be invoked against the entity source, which ruins the point of doing these steps, which would be executed in the database in my original code.
I am missing the last step of how to create a new Expression from fieldDelegate that can do a comparison, rather than just returning the string value. Will this approach work? How do I make the necessary Expression in WhereEqualIfSpecified to allow LINQ-to-Entities to execute it later?
What you're trying to do here is to compose expressions. Expressions, unlike delegates, are a bit tricker to compose. Here is one implementation of how to compose expressions. Once you have that Compose method you can write your extension method as:
public static IQueryable<T> WhereEqualIfSpecified<T>(
this IQueryable<T> query,
Expression<Func<T, string>> fieldExpression,
string filterValue)
{
return string.IsNullOrWhiteSpace(filterValue)
? query
: query.Where(fieldExpression.Compose(value => value == filterValue);
}
Ok, I am having a hard time trying to figure out how to setup a moq for a method that takes in an expression. There are a lot of examples out there of how to to It.IsAny<>... that is not what I am after. I am after doing with a constraint, so It.Is<>. I have set it up but it never returns the value I have asked it to return.
// Expression being setup
Expression<Func<UserBinding, bool>> testExpression = binding =>
binding.User.Username == "Testing Framework";
// Setup of what expression to look for.
this.bindingManager.Setup(
c => c.GetUserBinding(It.Is<Expression<Func<UserBinding, bool>>>
(criteria => criteria == testExpression)))
.Returns(new List<UserBinding>() { testBinding }.AsQueryable());
// Line of code call from within the class being tested. So this is being mocked and should return the defined object when the same lambda is passed in.
this.bindingManager.GetUserBinding(b => b.User.Username == username)
.SingleOrDefault();
// class under test. So for the test this is being called.
// so this is the method being called and inside this method is where the binding manager is being mocked and called.
var response = this.controller.SendMessage(message, true).Result;
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
// inside the controller.SendMessage method this method is called with the lambda expression. I have verified the usernames match but when the setup is It.Is this returns null instead of the object setup in the "setup" call.
this.bindingManager.GetUserBinding(b => b.User.Username == username)
.SingleOrDefault();
If I change the setup to It.IsAny... It works and returns the expected object setup in the "returns" method.
I have found a few examples of how to do this on the web one is doing it this way the other is using compile but I can't get that to work either. How do you get this to work for a specific expression?
Update with working solution based on answer
#carlos-alejo got me going in the right direction or at least kicked me back to the Compile action. I was thinking about it wrong. I have the solution working now based on using compile. The key thing to understand about compile is you are giving it an object by which to evaluate/generate the expression for.
So in my case if some one is giving me an expression like this:
binding => binding.User.Username == "Testing Framework";
I need to have a UserBinding like this:
var testBinding = new UserBinding { Binding = new Binding { Name = "Default binding" }, Domain = "test.com", User = new User() { Username = "Testing Framework" } };
I can then create my "setup" call like this:
this.bindingManager.Setup(c => c.GetUserBinding(It.Is<Expression<Func<UserBinding, bool>>>(y => y.Compile()(testBinding))))
.Returns(new List<UserBinding>() { testBinding }.AsQueryable());
This works and in my case returns me back the test binding object as I have setup. If you change the testBinding to be (notice I changed the user name):
var testBinding = new UserBinding { Binding = new Binding { Name = "Default binding" }, Domain = "test.com", User = new User() { Username = "Testing Framework2" } };
It will not work because the code inside my system under test generates an expression looking for "Test Framework"
Maybe it was just me not connecting the dots on this but hopefully it helps others.
It seems that the real problem here is how to compare two lambda expressions, as you try to do in the It.Is<Expression<Func<UserBinding, bool>>> (criteria => criteria == testExpression) clause. Using #neleus's answer to this question, I could come up with this test that actually passes:
readonly Mock<IBindingManager> bindingManager = new Mock<IBindingManager>();
[Test]
public void TestMethod()
{
Expression<Func<string, bool>> testExpression = binding => (binding == "Testing Framework");
bindingManager.Setup(c => c.GetUserBinding(It.Is<Expression<Func<string, bool>>>(
criteria => LambdaCompare.Eq(criteria, testExpression)))).Returns(new List<string>());
var oc = new OtherClass(bindingManager.Object);
var actual = oc.Test(b => b == "Testing Framework");
Assert.That(actual, Is.Not.Null);
bindingManager.Verify(c => c.GetUserBinding(It.Is<Expression<Func<string, bool>>>(
criteria => LambdaCompare.Eq(criteria, testExpression))), Times.Once());
}
Please note the use of the LambdaCompare.Eq static method to compare that the expressions are the same. If I compare the expressions just with == or even Equals, the test fails.
When I was looking for the way to to mock Where() and filter some data,
in code under tests looks like:
Repository<Customer>().Where(x=>x.IsActive).ToList()
I could design such example based on answers form others:
var inputTestDataAsNonFilteredCustomers = new List<Customer> {cust1, cust2};
var customersRepoMock = new Mock<IBaseRepository<Customer>>();
IQueryable<Customer> filteredResult = null;
customersRepoMock.Setup(x => x.Where(It.IsAny<Expression<Func<Customer, bool>>>()))
.Callback((Expression<Func<Customer, bool>>[] expressions) =>
{
if (expressions == null || expressions.Any() == false)
{
return;
}
Func<Customer, bool> wereLambdaExpression = expressions.First().Compile(); // x=>x.isActive is here
filteredResult = inputTestDataAsNonFilteredCustomers.Where(wereLambdaExpression).ToList().AsQueryable();// x=>x.isActive was applied
})
.Returns(() => filteredResult.AsQueryable());
Maybe it will be helpful for feather developers.
I am trying to edit a search tool using linq,
What I like a filter in where clause is (ItemNumber == X AND ( StatementStatus == SatusA Or StatementStatus == StatusB ) )
But right now, it is like:
What I like a filter in where clause is (ItemNumber == X AND StatementStatus == SatusA Or StatementStatus == StatusB )
as AND has higher operational priority over OR the result is not what I want. :)
Could you please help?
using (var ctx = new MyContext()) {
Func<Statement, bool> filter = null;
if (!string.IsNullOrEmpty(request.ItemNumber))
filter = new Func<Statement, bool>(s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber));
if (request.StatusA)
filter = filter == null ? new Func<Statement, bool>(s => s.StatementStatus == StatementStatusType.StatusA) :
filter.And(s => s.StatementStatus == StatementStatusType.StatusA);
if (request.StatusB)
filter = filter == null ? new Func<Statement, bool>(s => s.StatementStatus == StatementStatusType.StatusB) :
filter.Or(s => s.StatementStatus == StatementStatusType.StatusB);
var results = ctx.Statements
.Include("StatementDetails")
.Include("StatementDetails.Entry")
.Where(filter)
.Take(100)
.Select(s => new StatementSearchResultDTO{ ....
}
}
That's happens not because AND have higher priority than OR. What happens in reality:
var firstFilter = ...; // itemNumber
var secondFilter = ...; // statusA
var firstAndSecondFilter = firstFilter.And(secondFilter); // itemNumber && statusA
var thirdFilter = ...; // statusB
var endFilter = firstAndSecondFilter.Or(thirdFilter) // (itemNumber && statusA) || statusB.
The problem - wrong control flow. You must to do something like that:
var filterByA = ...;
var filterByB = ...;
var filterByAorB = filterByA.Or(filterByB);
var filterByNumber = ...;
var endFiler = filterByNumber.And(filterByAorB);
And your code is bad, not just because it works wrong, but because it's hard to write code in such style. Reasons:
This code doesn't follow DRY principle. You have two same lambdas that checks for StatusA (look in your ternary operator) and two same lambdas that checks for StatusB
You have too long ternary operator with null checks. That's bad because you don't see general picture, your eyes focused on syntax problems. You may write and extension method AndNullable for funcs. Like this:
static Func<T1, TOut> AndNullable<T1, TOut>(this Func<T1, TOut> firstFunc, Func<T1, TOut> secondFunc) {
if (firstFunc != null) {
if (secondFunc != null)
return firstFunc.And(secondFunc);
else
return firstFunc;
}
else {
if (secondFunc != null)
return secondFunc;
else
return null;
}
}
And that same for Or. Now your code can be wroted like this:
Func<Statement, bool> filter = null;
if (request.StatusA)
filter = s => s.StatementStatus == StatementStatusType.StatusA;
if (request.StatusB)
filter = filter.OrNullable(s => s.StatementStatus == StatementStatusType.StatusB);
if (!string.IsNullOrEmpty(request.ItemNumber))
filter = filter.AndNullable(s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber));
Reads more better.
Your filter is global filter. Writing of global filter is simpler for few filter conditions and number of lines is small, but it's more complicated to understand your filter. Rewrite it in this way:
Func<Statement, bool> filterByStatusA = null;
Func<Statement, bool> filterByStatusB = null;
if (request.StatusA)
filterByStatusA = s => s.StatementStatus == StatementStatusType.StatusA;
if (request.StatusB)
filterByStatusB = s => s.StatementStatus == StatementStatusType.StatusB;
Func<Statement, bool> filterByStatuses = filterByStatusA.OrNullable(filterByStatusB);
Func<Statement, bool> filterByItemNumber = null;
if (!string.IsNullOrEmpty(request.ItemNumber))
filterByItemNumber = s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber);
Func<Statement, bool> endFilter = filterByItemNumber.And(filterByStatuses);
Okay, we have outthinked how we can write filters by combining them as Func<..> but we still have problems.
What problems we will got, if result filter is null? Answer: ArgumentNullException due to documentation. We must to think about this case.
What another problems we can got with using of simple Func<...>? Well, you must to know difference between IEnumerable<T> and IQueryable<T> interfaces. In simple words, all operations on IEnumerable causes simple iteratation over all elements (well, it's lazy, IEnumerable really slower than IQueryable). So, for example, combining of Where(filter), Take(100), ToList() on collection that have 10000 elements that are bad for this filter and 400 elements that are good will cause iterating over 10100 elements. If you wrote similar code for IQueryable the request of filtering will send on database server and this server will iterate only ~400 (or 1000, but not 10100), if you have configured indexes on database. So what happens in your code.
var results = ctx.Statements // you are getting DbSet<Statement> that implements interface IQueryable<Statement> (and IQueryable<T> implements IEnumerable<T>)
.Include("StatementDetails") // still IQueryable<Statement>
.Include("StatementDetails.Entry") // still IQueryable<Statement>
.Where(filter) // Cuz your filter is Func<..> and there are no extension methods on IQueryable that accepts Func<...> as parameter, your IQueryable<Statement> casted automatically to IEnumerable<Statement>. Full collection will be loaded in your memory and only then filtered. That's bad
.Take(100) // IEnumerable<Statement>
.Select(s => new StatementSearchResultDTO { .... // IEnumerable<Statement> -> IEnumerable<StatementSearchResultDTO>
}
Okay. Now you understand the problem. So, simple right code for you can be writed in this way:
using (var ctx = new MyContext()) {
results = ctx.Statements
.Include("StatementDetails")
.Include("StatementDetails.Entry")
.AsQueryable();
if (!string.IsNullOrEmpty(request.ItemNumber))
results = results.Where(s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber));
if (request.StatusA) {
if (request.StatusB)
results = results.Where(s => s.StatementStatus == StatementStatusType.StatusA ||
s.StatementStatus == StatementStatusType.StatusA);
else
results = results.Where(s => s.StatementStatus == StatementStatusType.StatusA);
}
else {
if (request.StatusB) {
results = results.Where(s => s.StatementStatus == StatementStatusType.StatusB);
}
else {
// do nothing
}
}
results = .Take(100)
.Select(s => new StatementSearchResultDTO{ ....
};
// .. now you can you results.
}
Yeah, totally ugly, but now your database solves how to find Statements that satisfy the filter. Therefore, this request is quickly as possible. Now we must understand what magic happens in code I written upper. Let's compare two examples of code:
results = results.Where(s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber));
And this:
Func<Statement, bool> filter = s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber);
results = results.Where(filter);
What the difference? Why first is more faster? Answer: when compiler sees first code, it examines that type of results is IQueryable<T> and IEnumerable<T> so that condition inside of brackets can have type Func<Statement, bool> (compiled function) or Expression<Func<Statement, bool>> (data, that can be compiled in function). And compiler chooses Expression (why - really dunno, just chooses). After request of first object query compiled not in C# statement, but in SQL statement and sends to server. Your SQL server can optimize request, because of indexes existing.
Well, the more better way - to write your own expressions. There are different ways to write your own expression, but there is a way to write it with not ugly syntax. The problem that you can't just invoke one expression from another - that doesn't supported by Entity Framework and can be not supported by another ORM's. So, we can use PredicateBuilder by Pete Montgomery: link. And then write two simple extensions on expressions suitable for us.
public static Expression<Func<T, bool>> OrNullable<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
if (first != null && second != null)
return first.Compose(second, Expression.OrElse);
if (first != null)
return second;
if (second != null)
}
And that same for And. And now we can write our filter:
{
Expression<Func<Statement, bool>> filterByStatusA = null;
Expression<Func<Statement, bool>> filterByStatusB = null;
if (request.StatusA)
filterByStatusA = s => s.StatementStatus == StatementStatusType.StatusA;
if (request.StatusB)
filterByStatusB = s => s.StatementStatus == StatementStatusType.StatusB;
Expression<Func<Statement, bool>> filterByStatuses = filterByStatusA.OrNullable(filterByStatusB);
Expression<Func<Statement, bool>> filterByItemNumber = null;
if (!string.IsNullOrEmpty(request.ItemNumber))
filterByItemNumber = s => s.StatementDetails.Any(sd => sd.ItemNumber == request.ItemNumber);
Expression<Func<Statement, bool>> endFilter = filterByItemNumber.And(filterByStatuses);
requests = ...;
if (endFilter != null)
requests = requests.Where(endFilter);
}
You can got a problem, because class ExpressionVisitor in PredicateBuilder in .NET < 4.0 is sealed. You can get write your own ExpressionVisitor or just copy it from this article.
OK, here is the way I have solved it:
filter.And(s => (request.StatusA && s.StatementStatus == StatementStatusType.StatusA) ||
(request.StatusB && s.StatementStatus == StatementStatusType.StautsB) ||
!(request.StatusA || request.StatusB)); //None selected = All selected
Any comments?
I have a method in my project that repeats over and over:
public PAC PAC_GetByCodiPac(string codiPac)
{
var sel = _gam.PAC.Where(pac => pac.CODI_PAC == codiPac);
if (sel.Count() > 0)
return sel.First();
return null;
}
The table PAC means (patient), so I have these methods for all the tables I have.
How can I make a generic method for this?
Thanks in advance.
Here is your generic method. Note, that as others pointed out FirstOrDefault is better than count and then first, so I'm using it here. But it's also possible to write the expression so that it mimics what your original code does. Please let me know if you need additional help with this.
public static T GetByCodi<T>(IQueryable<T> table, string codi, string fieldName) where T : class
{
// x
ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
Expression currentExpression = parameter;
Type currentType = typeof(T);
PropertyInfo property = currentType.GetProperty(fieldName);
// x.CODI_xxx
currentExpression = Expression.Property(currentExpression, property);
// x.CODI_xxx == codi
currentExpression = Expression.Equal(currentExpression, Expression.Constant(codi));
// x => x.CODI_xxx == codi
LambdaExpression lambdaExpression = Expression.Lambda(currentExpression, parameter);
return table.FirstOrDefault((Func<T, bool>)lambdaExpression.Compile());
}
You use it like this:
PAC xxx = GetByCodi<PAC>(_gam.PAC, codiPac, "CODI_PAC");
Edit 1:
I changed the code according to the comment so that you can pass arbitrary ID field name in.
I see that what you asked is a very straight forward where query even doesn't require to have have it on a separate method.
Also you can simply enhance your query link the following:
public PAC PAC_GetByCodiPac(string codiPac)
{
return _gam.PAC.FirstOrDefault(pac => pac.CODI_PAC == codiPac);
}
FirstOrDefault will return the first item on the array, if not it will return null.
If you want a generic method that lets you specify any table and any predicate for records from that table then you can't really get any better than the built-in Where<T>(...) and (as others have already pointed out) the FirstOrDefault<T>(...) extension methods.
Your code would then look like so:
var result = _gam.PAC.Where(pac => pac.CODI_PAC == codiPac).FirstOrDefault();
// OR
var result = _gam.PAC.FirstOrDefault(pac => pac.CODI_PAC == codiPac);
The best you could get then, writing your own generic method, would be this:
public T FirstOrDefault<T>(IQueryable<T> source,
Expression<Func<T, bool>> predicate)
{
return source.Where(predicate).FirstOrDefault();
// OR
// return source.FirstOrDefault(predicate);
}
And that is really just redundant. Especially when your calling code would be actually longer using the helper method:
var result = FirstOrDefault(_gam.PAC, pac => pac.CODI_PAC == codiPac);
// versus
var result = _gam.PAC.FirstOrDefault(pac => pac.CODI_PAC == codiPac);
And even worse, your code is no longer using a fluent, composable syntax. This just makes readability and maintenance more difficult.
If you stick with using the IQueryable<T> extension methods then you can do composition like this:
var result = _gam.PAC
.Where(pac => pac.CODI_PAC == codiPac)
.Where(pac => pac.SomeOtherProperty == someOtherValue)
.FirstOrDefault();
// OR
var result = (from pac in _gam.PAC
where pac.CODI_PAC == codiPac
where pac.SomeOtherProperty == someOtherValue
select pac).FirstOrDefault();
One very important thing to note here is that the predicate parameter in the IQueryable<T>.Where<T>(...) extension method is of type Expression<Func<T, bool>>. This allows the IQueryable<T> provider to construct the native SQL (or other native provider query) at the very last moment before returning a result.
Not using Expression<Func<T, bool>> means that your query would be the equivalent of this:
var result =
_gam.PAC
.ToArray()
.Where(pac => pac.CODI_PAC == codiPac)
.FirstOrDefault();
And that would mean the query will load every record from the "PAC" table into memory before selecting the first filtered result and throwing out the rest of the results.
The bottom-line is that by making a generic helper method you are rewriting existing framework code and you open yourself to performance and maintenance issues while also reducing code readability.
I hope this helps.
I'm not sure if you are asking for this, but this method could be in a static class and method and so you'd be able to call it from everywhere.
An easy solution will be:
//a generic method
private PAC PAC_GetPAC(Func<PAC, bool> predicate)
{
return _gam.PAC.Where(predicate).FirstOrDefault();
}
public PAC PAC_GetPACById(long id)
{
return PAC_GetPAC(p => p.ID == id);
}
public PAC PAC_GetByCodiPac(string codiPac)
{
return PAC_GetPAC(p => pac.CODI_PAC == codiPac);
}