When checking that the correct data is being used to call a method I can do this:
mockedClass.Verify(method => method.WriteToConsole(It.Is<Result>(item => item.Name == "Bob" && item.Age == 44)));
where Results is an object that is the output from a Linq query:
public class Result
{
public string Name { get; set; }
public int Age { get; set; }
}
However, I also use IEnumerable as the input to a 2nd method.
How do I amend the Verify above to check that the IEnumerable of Results contains Results I can test against.
mockedClass.Verify(method => method.WriteListToConsole(It.Is<IEnumerable<ResultRecord>>(item => What GOES HERE?)));
"item" at that point is an IEnumerable<ResultRecord>. Just write what you want to test.
Something like this?
mockedClass.Verify(method => method.WriteListToConsole(It.Is<IEnumerable<ResultRecord>>(item => item.Count() == 1 && item.ToList()[0].SomeProperty == "Something")));
Related
I have this function that returns 2 strings
public object GetNamePhoneByUserId(int userId)
{
return _db.ApplicationUsers.Where(q => q.UserId == userId).Select(a => new {
a.FullName,a.PhoneNumber}).ToList();
}
When calling the function, i'm getting the values, but unable to extract them from the returned value(appU)
object appU = _unitOfWork.ApplicationUser.GetNamePhoneByUserId(ca.UserId);
i was able to cast it to Ienumerable but still can't extract the values..
IEnumerable list = (IEnumerable)appU;
I'm sure its a simple solution, but tried many things and still not working.
Thank you
Don't say that your method returns an object. You're going to have a really tough time working with the data, as you've seen.
Instead, create a class to represent the fields you're returning, and return a collection of that class.
public class ApplicationUserMinimalInfo // make this more descriptive as needed
{
public string FullName { get; set;}
public string PhoneNumber {get; set;}
}
public List<ApplicationUserMinimalInfo> GetNamePhoneByUserId(int userId)
{
return _db.ApplicationUsers
.Where(q => q.UserId == userId)
.Select(a => new ApplicationUserMinimalInfo
{
a.FullName,
a.PhoneNumber
}).ToList();
}
Now, I also suspect that because you're filtering by the UserId, you should only be getting a single result back, or no results back. It doesn't make sense to get two records with the same UserId.
public ApplicationUserMinimalInfo? GetNamePhoneByUserId(int userId)
{
var user = _db.ApplicationUsers
.SingleOrDefault(q => q.UserId == userId); // uses "Where" logic
if (user is null)
return null;
else
return new ApplicationUserMinimalInfo
{
user.FullName,
user.PhoneNumber
});
}
Now, unless you really have some super pressing reason to have a method that returns a subset of properties, just return the full object.
public ApplicationUser? GetUserById(int userId)
{
return _db.ApplicationUsers
.SingleOrDefault(q => q.UserId == userId);
}
Or better yet, this method is a single line, it doesn't really need to be its own method.
I am using Entity Framework Core with SQL Server to filter a list of division entities by a list of passed in search objects. I want to return division that match the criteria in any one of the search objects. The search object class looks like:
public class SearchObject
{
public int DivisionId { get; set; }
public int Status { get; set; }
}
Here is the query I tried:
var searchObjects = new List<SearchObject> { ... };
IQueryable<Product> query = myContext.Divisions.Where(div =>
searchObjects.Any(searchObj =>
searchObj.Status == div.Status &&
searchObj.DivisionId == div.DivisionId))
.Select(...);
When the IQueryable enumerates, I get an error stating: "The Linq Expresion DbSet ... Could not be translated ..." What I need is something like .Contains(), but that works with a list of SearchObj.
Well you have the right idea by
What I need is something like .Contains(), but that works with a list of SearchObj.
and this is how you'd do it
var searchObjects = new List<SearchObject> { ... };
var searchIds = searchObjects.Select(x => x.Divisiond) //.ToList() perhaps?
var searchStatus = searchObjects.Select(x => x.Status) //.ToList() perhaps?
//not you can simply use .Contains and it should generate a WHERE EXISTS query
IQueryable<Product> query = myContext.Divisions
.Where(div =>
searchIds.Contains(div.DivisionId) &&
searchStatus.Contains(div.Status))
.Select(...);
I'm trying to retrieve a few records from a table given a certain condition... this is my code:
var areas = _context.Set<T>()
.Where(p => (int)p.GetType().GetProperty(campoOrdem).GetValue(p) >= indexMin &&
(int)p.GetType().GetProperty(campoOrdem).GetValue(p) <= indexMax).ToList();
I am getting this error :
'The LINQ expression 'DbSet<RH_Cargos>
.Where(r => (int)r.GetType().GetProperty(__campoOrdem_0).GetValue(r) >=
__indexMin_1 && (int)r.GetType().GetProperty(__campoOrdem_0).GetValue(r) <=
__indexMax_2)' could not be translated.
All of my variables are getting the correct values.. campoOrdem is the string which contains the name of the field, indexMin and indexMax is my values of order in the database, in the example, indexMin is 1, and indexMax is 2...
what is happening?
Reflection won't work for what you are trying to do, but if the property always has the same name, you could use generic constraints (if you can add that interface to all relevant entities):
public interface IEntityWithCampoOrdem
{
public int CampoOrdem { get; } // property name should always be the same
}
This assumes that entities like RH_Cargos can be defined like so:
public class RH_Cargos : IEntityWithCampoOrdem
{
// other properties
public int CampoOrdem { get; set; }
}
Now you can create a generic method like so:
public void GetAreas<T>() where T : IEntityWithCampoOrdem
{
var areas = _context.Set<T>()
.Where(p => p.CampoOrdem >= indexMin &&
p.CampoOrdem <= indexMax).ToList();
}
i struggling to find the correct way to query for a specific entity in my database. I have a table TeamMember which looks as follows:
public class TeamMember
{
public Guid TeamId { get; set; }
public Guid ManagerUserId { get; set; }
...
}
At several positions i want to query for a "TeamManager" in my teams.
public TeamMember GetTeamManager(Guid teamId, List<TeamMember> teamMembers)
{
return teamMembers.FirstOrDefault(member => member.TeamId == teamId && member.ManagerUserId == null);
}
If i want to use a method in an expression e.g (not real code),
...
// IQueryable<TeamMember>
teamMembers.Where(member => member.team.GetTeamManager(teamId, teamMembers))
it works fine for in memory objects, but this does not work in combination with the entity framework, so real db objects.
Therefore i was experimenting with static expressions, but i did not find any solution which uses a static expression in combination with a variable e.g.:
// this should be an ideal solution
Expression<Func<TeamMember, bool>> exp = teammember => teamMember.TeamId == **CUSTOM_VARIABLE** && teamMember.ManagerUserId == null;
teamMembers.Where(exp)
I want to reuse the expression, but i also want to be able to modify the variable. My goal is to avoid the creation of an object in between because the following would work, but is less efficient (correct me if i'm wrong)
teamMembers.ToList().Where(member => member.team.GetTeamManager(teamId, teamMembers))
So please help me with my problem :).
Thank you in advance!
You can't make exp a property because of the need to capture a variable, but you can make it a function returning Expression<Func<TeamMember,bool>>:
Expression<Func<TeamMember,bool>> MakeMemberExpression(Guid teamId) {
return teammember => teamMember.TeamId == teamId && teamMember.ManagerUserId == null;
}
or even
Expression<Func<TeamMember,bool>> MakeMemberExpression(Guid teamId) =>
teammember => teamMember.TeamId == teamId && teamMember.ManagerUserId == null;
You can use it as follows:
var members = teamMembers.Where(MakeMemberExpression(teamId));
You can create a function that operates on IQueryable.
public TeamMember GetTeamManager(IQueryable<TeamMember> baseQuery,Guid teamId)
{
return baseQuery.FirstOrDefault(member => member.TeamId == teamId && member.ManagerUserId == null);
}
I am using entity framework code first. I have a collection let's say:
IDbSet<A> As {get;set;}
A is an object like this:
public class A
{
public int Id {get;set;}
public string name {get;set};
....
public IList<B> Bs {get;set;}
}
and B is:
public clas B
{
public int Id {get;set;}
public string name {get;set;}
}
Using linq I want to filter the As which contains B.name == "something" in its IList so how to achieve this? I am trying to do something like:
context.As.Where(a => a.Bs.contains(....));
You can use Any()
context.As.Where(a => a.Bs.Any(b => b.name == "something").ToList();
It takes a predicate and returns upon a match making it efficient.
I would use the Any() method.
var result = context.As.Where(a => a.Bs.Any(b => b.Name == "something"));
Well, yes, you do it like that:
var AsWithSomethingBs =
context.As.Where(a => a.Bs.Any(b => b.Name == "Something"));
This basically says: give me all the As where any of the A's Bs have a name that is equal to "Something"
context.As.Where(a => a.Bs.Any(x => x.name=="something"));