Linq to SQl - single result - linq-to-sql

I have been playing with the Linq to Sql and I was wondering if it was possible to get a single result out? For example, I have the following:
using(DataClassContext context = new DataClassContext())
{
var customer = from c in context.table
where c.ID = textboxvalue
select c;
}
And with this I need to do a foreach around the var customer but i know that this will be a single value! Anyone know how I could do a textbox.text = c.name; or something along that line?

Yes, it's possible.
using(DataClassContext context = new DataClassContext())
{
var customer = (from c in context.table
where c.ID = textboxvalue
select c).SingleOrDefault();
}
This way you get 1 result or null if there isn't any result.
You can also use Single(), which throws an exception when there isn't a result.
First() will give you only the first result found, where Last() will give you only the last result, if any.
Here's an Overview of all Enumerable methods.

var customer = context.table.SingleOrDefault(c => c.ID == textboxvalue);

Related

Linq to entity adding Where() clause breaks query

Using Microsoft SQL Entity Framework I've got a query where sometimes I have a filter condition and sometimes I don't, so I tried to do what I've shown below. If the condition is not null then instead of doing the query as expected it queries everything from the Org_Hierarchy table, and then queries everything from the Workers table, and then dies as that takes too long:
void SomeMethod(Func<PRT, bool> whereClause) {
IQueryable<PRT> query;
if (whereClause != null) {
query = PRT.Where(whereClause).AsQueryable();
} else {
query = PRT.AsQueryable();
}
var data = from prt in query
// LEFT OUTER JOIN Worker a ON prt.assigned_to = a.WWID
join a_join in Worker on prt.assigned_to equals a_join.WWID into a_grp
from a in a_grp.DefaultIfEmpty()
// LEFT OUTER JOIN Worker c ON prt.closed_by = c.WWID
join c_join in Worker on prt.closed_by equals c_join.WWID into c_grp
from c in c_grp.DefaultIfEmpty()
// LEFT OUTER JOIN Worker r ON prt.requestor = r.WWID
join r_join in Worker on prt.requestor equals r_join.WWID into r_grp
from r in r_grp.DefaultIfEmpty()
// LEFT OUTER JOIN Org_Hierarchy o ON prt.org3 = o.OrganizationHierarchyUnitCd AND o.OrganizationHierarchyUnitTreeLevelNbr = 3 AND o.Active = true
join o in Org_Hierarchy on prt.org3 equals o.OrganizationHierarchyUnitCd
select new PrtInput {
If I change the query and put something direct in there, just for testing, like where prt.id == Guid.NewGuid() right above the last line shown then the query returns in one second. What's the trick to be able to dynamically add a where clause to the query?
The above code is from LinqPAD which is why the normal "context" stuff is all missing.
I'm not sure , but i think you should use something like this :
Expression<Func<PRT ,bool>> whereClause
Insted of:
Func<PRT ,bool> whereClause
When you using Func<> , first fetch data from db to memory then filter data in memory ,but if you use Epression<> filter send to sql and return result.
Also for the better performnce you can use AsNoTracking() like this:
if (whereClause != null) {
query = PRT.Where(whereClause).AsQueryable().AsNoTracking();
} else {
query = PRT.AsQueryable().AsNoTracking();
}
When you only want run query on yout database without any Insert ,update or delete on result , it better use AsNoTracking.
I hope this answers your question.

Linq-select group by & count

A controller should return data that is used as source for a D3.js line chart. In the controller, I've got a list of objects and I'm only interested in the property "Begin" and count(Begin). Begin is a datetime and what I want is to group all Objects where "Begin" is on the same day, and then count the number for each day.
I try to select this information and return it this way:
var results = from a in db.Questionaires
group a by a.Begin.Date into g
select new { Date = g.Key, Count = g.Count() };
return Json( results, JsonRequestBehavior.AllowGet);
Unfortunatly, I'm getting an error because the group by clause seems to be wrong ("The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.").
How to select the information the right way? If anybody has some examples on D3.js and MVC I would appreciate that.
You should try this
var results = from a in db.Questionaires
group a by new { y = a.Begin.Year, m = a.Begin.Month, d = a.Begin.Day}
into g
select new { Day = g.Key.d, Year = g.Key.y,
Month = g.Key.m, Count = g.Count(),
Date = g.Select(d=>d.Begin).FirstOrDefault() };

equivalent LINQ query

I have a history table for Students in SQL Server 2008.
StudentHistoryId, StudentId, Grade, CreatedAt, ModifiedAt, ModifiedBy, Active
I am new to LINQ.
How do I write a LINQ query to get the latest modified row for all the active students and also the equivalent sql query for the same ?
Something like (Assuming LINQ-SQL):
using (YourDataContext db = new YourDataContext())
{
var data = from s in db.Students
select new
{
StudentId = s.StudentId,
LastHistory = s.Histories
.OrderByDescending(s => s.ModifiedAt)
.Where(s => s.Active)
.FirstOrDefault()
};
}
This is assuming that you want all students, regardless of whether they actually have any history. If don't want this, you can start with the History table and group by Student ID.
To view the SQL, you can hover the variable in debugging to see the SQL produced. I'm too lazy to convert the LINQ ;-)
var q =
from h in history
where h.Active
group h by new { h.StudentId, h.Grade } into g
select new
{
StudentId = g.Key.StudentId,
Grade = g.Key.Grade,
LatestModified = g.Max (x => x.ModifiedAt)
}
LINQ
var tempresult = (from student in Students
where Active == true).OrderByDesc(ModifiedAt)
List<Student> results = new List<Student>();
foreach(var result in tempResult)
{
if((results.Where(r => r.StudentId == result.StudentId).FirstOrDefault()) == null)
{
results.Add(result);
}
}
SQL
Select [Rows]
From Students S
Where S.Active = 1
And S.ModifiedAt = (Select Max(ModifiedAt)
From Student S1
Where S1.StudentId = S.StudentId)
The Linq is hacky (and I'm sure there's a better way, but I can't remember it) and I'm only sort-of confident about the SQL syntax (though that should point you in the right direction even if it's not exactly right), but either of those should get: The maximum ModifiedAt for every student that is currently active.
.FirstOrDefault() [LINQ] or Top 1 would only select the single row (only one student) with the most recent ModifiedAt.

NHibernate CreateSqlQuery and addEntity

The hibernate manual says this:
String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +
"BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " +
"FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";
List loggedCats = sess.createSQLQuery(sql)
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class).list()
Now, what I have is basically the same. I am return two of the same type per row. I am doing a select something like this:
SELECT {ctrl1.*}, {ctrl2.*} FROM tableA AS A
LEFT JOIN tableB AS ctrl1 ON (A.controlID = ctrl1.controlID AND ctrl1.controlOptionType = ? AND ctrl1.controlOptionValue = ?)
LEFT JOIN tableB AS ctrl2 ON (A.controlID = ctrl2.controlID AND ctrl2.controlOptionType = ? AND ctrl2.controlOptionValue = ?)
And then I addEntity("ctrl1", typeof(mycontrolclass) and
addEntity("ctrl1", typeof(mycontrolclass)
Which seems exactly the same to me as their example. But I get this exception:
"Could not execute query" and the inner exception is "Could not find specified column in results".
If I copy the sql in the exception(to which it has added "AS ctrl1_1_3_3_" etc) it works fine.
Thanks.
What exactly are you trying to do? I believe you might not need using either of them.
// Using HQL:
var motherId = 25;
var hql = "select c.birthDate, c.mother from Cat c where c.mother.Id = :motherId";
var result = Session.CreateQuery(hql)
.SetParameter("motherId", motherId)
.ToList();
// Using NHibernate.LINQ:
var result = (from cat in Session.Linq<Cat>()
where cat.Mother.Id == motherId
select new { cat.birthDate, cat.mother }).ToList();
HQL query examples.
LINQ for NHibernate examples.
I dealt with your problem just for studying purposes, because you will surely
have found a solution in the meanwhile, but the problem should not lie in
the query (which is ok), but in some mapping inconsistency or somewhere else
(perhaps Database).

Using one LINQ statement with different parameters

I have a pretty complex linq statement I need to access for different methods. Each of these methods may need to see the resulting data with different parameters. For one method it may be a project code, for another it may be language. The statement is pretty much the same it's just the where part which changes.
I have not been able to figure out how to use different where statements without duplicating the entire linq statement, and that just isn't dry enough for me.
For example (greatly simplified):
var r = from c in customer
where c.name == "some name"
// or it may be
var r = from c in customer
where c.customerId == 8
Is there a way to have both of these in the same statement so I can use one or the other based on what I am doing? I tried an if statement to use one of the where statements or the other, and that didn't go over very well.
You can do it like this:
var r = from c in customer
select c;
if (CustomerName != null)
r = r.Where(c => c.name == CustomerName);
if (CustomerID != null)
r = r.Where(c => c.customerId == CustomerID);
You could make these else if if only one should apply, in my example any criteria that wasn't null would be applied to the query to filter on.
what about something like this?
var useIdForFiltering = false;
var r = from c in customer
where (useIdForFiltering && c.customerId == 8) || (c.name == "some name")
You can pass in a Func delegate to your function (the Where clause takes a Func delegate with a boolean return type). Then use this delegate in the Where clause.