Get distinct value from database - linq

I want to get the distinct list of studentname from the database who are still active. Ihis is what I've tried.
string strJSON = JsonConvert.SerializeObject(
context.Students.Where(x => x.IsActive == 1).Distinct().ToList());

Distinct function works on all columns, so I assume that you want only student name.
string strJSON = JsonConvert.SerializeObject(
context
.Students
.Where(x => x.IsActive==1)
.Select(x=>x.StudentName)
.Distinct()
.ToList()
);

Related

LINQ to SQL - WHERE clause filtered

Why is the where condition not applied in the following code? When I search, the results are not getting filtered. When I debug, searchString does have a value and execution is going through the _data.Where clause but it's not returning the filtered result.
What I'm doing wrong here?
IQueryable<UserViewModel> _data = (
from a in context.aspnet_Users
join b in context.aspnet_Membership on a.UserId equals b.UserId
where b.IsApproved == true
select new UserViewModel
{
UserId = a.UserId,
UserName = a.UserName,
FirstName = a.FirstName,
LastName = a.LastName,
EmailAddress = b.Email
})
.OrderBy(a => a.FirstName)
.ThenBy(b => b.LastName);
if (!String.IsNullOrEmpty(searchString))
{
_data = _data
.Where(x => x.FirstName.Contains(searchString))
.Where(y => y.UserName.Contains(searchString))
.Where(y => y.LastName.Contains(searchString))
.Where(y => y.EmailAddress.Contains(searchString));
}
The way the second query is written checks for records where all filtered fields start with the search string, ie for users whose FirstName and LastName and UserName and Email all start with the same string.
I think what you wanted was a query that check whether any of these fields starts with the search string, eg:
_data = _data.Where(x => x.FirstName.Contains(searchString) ||
x.UserName.Contains(searchString) ||
x.LastName.Contains(searchString) ||
x.EmailAddress.Contains(searchString));
I suspect this is doing a lot more "filtering" than you expect:
_data = _data.Where(x => x.FirstName.Contains(searchString))
.Where(y => y.UserName.Contains(searchString))
.Where(y => y.LastName.Contains(searchString))
.Where(y => y.EmailAddress.Contains(searchString));
This requires that searchString exist in all four of those fields. So if you search for, say, "David" then it's going to fail to find my record because my LastName doesn't contain that string.
Perhaps you wanted to use a logical or instead of a logical and? Something like this:
_data = _data.Where(x => x.FirstName.Contains(searchString) ||
x.UserName.Contains(searchString) ||
x.LastName.Contains(searchString) ||
x.EmailAddress.Contains(searchString));

Getting the Error in my code when framing LINQ

My Code:
var lastName = employees
.Where(a => a.Number ==
(dm.MTM.Where(b => b.MTT.IsManager)
.Select(c => c.Number)
.FirstOrDefault()))
.Select(z => z.LastName)
.FirstOrDefault();
Error Message:
Unable to create a constant value of type 'XXX.Models.Mt.MTM'. Only primitive types or enumeration types are supported in this context.
Try:
int? num = dm.MTM.Where(b => b.MTT.IsManager).Select(c => c.Number).FirstOrDefault();
var lastName = employees.Where(a => a.Number == num).Select(z => z.LastName).FirstOrDefault();
But you should add a check
if (num == null)
{
// bad things, don't execute second query
}
between the two instructions.
The error is because in an Entity Framework query you can't do "things" too much fancy, like the things necessary to calculate num.
Try:
// Calculate the number outside of the main query
// because the result is fixed
var nb = dm.MTM
.Where(b => b.MTT.IsManager)
.Select(c => c.Number)
.FirstOrDefault();
// Perform the main query with the number parameter already calculated before
string lastName = String.Empty;
if (nb != null) // if null no need to run the query
{
lastName = employees
.Where(a => a.Number == nb)
.Select(z => z.LastName)
.FirstOrDefault();
}
You don't need to get the number from the database for each employee, calculate the value before running your main query.
This will be faster, less error-prone and better for caching.

LINQ read Select values

I have a LINQ query where I want to select and read the p.Api value.
var api = DataAccessNew.Instance.dcServers.Where(p => p.Ip == IpAddress).Select(p => p.Api);
How do I read the p.Api value?
I have tried api.ToString() but I get SQL instead of actual column value.
You are getting an IEnumerable<> back (and your ToString call is showing you the value of that expression).
If you are expecting a single value, do this:
var api = DataAccessNew.Instance.dcServers
.Where(p => p.Ip == IpAddress)
.Select(p => p.Api)
.Single();
You might be interested to read about the other methods like Single(): SingleOrDefault, First, FirstOrDefault. Which one you used depends on whether you are expecting a single or multiple values returned (Single vs. First) and what you want to happen if there are no values (the *Default methods will return the type default instead of throwing an exception).
Or if you want to look at all the returned values:
var api = DataAccessNew.Instance.dcServers
.Where(p => p.Ip == IpAddress)
.Select(p => p.Api);
foreach (var apiValue in api)
{
// apiValue will have the value you're looking for.
}
Try this snippet of code:
string apiValue = api.FirstOrDefault().ToString();
your syntex seems ok..
By the way try this
string api =DataAccessNew.Instance.dcServers.Where(p => p.Ip == IpAddress).Select(p => p.Api).FirstOrDefault();
if p.Ip is a unique key in your table you could try to add .FirstOrDefault() after your Linq query.
public string getselectedvalue(ListBox l)
{
string vtext="",vval="";
var selectedQueryText = l.Items.Cast<ListItem>().Where(item => item.Selected);
var selectedQueryVal = l.Items.Cast<ListItem>().Where(item => item.Selected).Select(item => item.Value);
vtext= String.Join("','", selectedQueryText ).TrimEnd();
vval= String.Join("','", selectedQueryVal ).TrimEnd();
return v;
}

Groupby and where clause in Linq

I am a newbie to Linq. I am trying to write a linq query to get a min value from a set of records. I need to use groupby, where , select and min function in the same query but i am having issues when using group by clause. here is the query I wrote
var data =newTrips.groupby (x => x.TripPath.TripPathLink.Link.Road.Name)
.Where(x => x.TripPath.PathNumber == pathnum)
.Select(x => x.TripPath.TripPathLink.Link.Speed).Min();
I am not able to use group by and where together it keeps giving error .
My query should
Select all the values.
filter it through the where clause (pathnum).
Groupby the road Name
finally get the min value.
can some one tell me what i am doing wrong and how to achieve the desired result.
Thanks,
Pawan
It's a little tricky not knowing the relationships between the data, but I think (without trying it) that this should give you want you want -- the minimum speed per road by name. Note that it will result in a collection of anonymous objects with Name and Speed properties.
var data = newTrips.Where(x => x.TripPath.PathNumber == pathnum)
.Select(x => x.TripPath.TripPathLink.Link)
.GroupBy(x => x.Road.Name)
.Select(g => new { Name = g.Key, Speed = g.Min(l => l.Speed) } );
Since I think you want the Trip which has the minimum speed, rather than the speed, and I'm assuming a different data structure, I'll add to tvanfosson's answer:
var pathnum = 1;
var trips = from trip in newTrips
where trip.TripPath.PathNumber == pathnum
group trip by trip.TripPath.TripPathLink.Link.Road.Name into g
let minSpeed = g.Min(t => t.TripPath.TripPathLink.Link.Speed)
select new {
Name = g.Key,
Trip = g.Single(t => t.TripPath.TripPathLink.Link.Speed == minSpeed) };
foreach (var t in trips)
{
Console.WriteLine("Name = {0}, TripId = {1}", t.Name, t.Trip.TripId);
}

Find the max value in a grouped list using Linq

I have a linq expression that returns transactions in groups. Each transaction has a numerical value and I now need to know what is the highest value from all the transactions returned. This value is held in a field called TransactionId
Here is the expression I am using to get the grouped list.
var transactions = ctx.MyTransactions
.Where (x => x.AdapterId == Id)
.GroupBy(x => x.DeviceTypeId);
I now need to write an expression that works on the “transactions” grouped list to find the “max” of the TransactionId field. I’ve tried different ideas but none seem to work with the grouped results. I’m new to linq so I’m not sure how to do this.
Have you tried finding the maximum in each group and then finding the maximum of that over all groups?
int max = transactions.Max(g => g.Max(t => t.TransactionId));
Or you could just query the database again:
int max = ctx.MyTransactions
.Where(x => x.AdapterId == Id)
.Max(t => t.TransactionId);
This will give you the max in each group
var transactionIds = ctx.MyTransactions
.Where (x => x.AdapterId == Id)
.GroupBy(x => x.DeviceTypeId,
g => new {
DeviceTypeId = g.Key,
MaxTransaction = g.Max(x => x.TransactionId)
});

Resources