I am currently developing a WPF project in c#. The project takes a string (newMemoryRFID) which is defined when the page is initialised and uses it in a query. Like so
var query =
from c in MemoryData.Memory
where c.RFID == newMemoryRFID
select c;
this.DataContext = query;
this.View = ((CollectionView)(CollectionViewSource.GetDefaultView(this.DataContext)));
This produces an empty DataContext
However when I use test data which is the same as what newMemoryRFID would be the query i.e.
var query =
from c in MemoryData.Memory
where c.RFID == "0F02D76B05"
select c;
this.DataContext = query;
this.View = ((CollectionView)(CollectionViewSource.GetDefaultView(this.DataContext)));
The query gets the correct record. As you may be able to tell I'm not the best programmer so the simpler your answer the better. And thanks very much in advance
This is the time to use your debugger. It sounds like newMemoryRFID isn't set to "0F02D76B05" at the time that query is created.
If you can't step into it, at least do
Debug.WriteLine(string.Format("newMemoryRFID = {0}", newMemoryRFID);
before the line
var query = ...
Try trimming the string both at the beginning and end for possible whitespace which would fail the string match.
Related
Is there any way to customize it?
This is what Im trying to do:
string customSelect = "c.person_name";
int per = PersonID();
var RetrievItem = (from c in db.person where c.person_id == per select new { customSelect }).FirstOrDefault();
I've tried to debugging it but it just ended up retrieving given string instead of value from database
Any suggestions #_ #?
In addition to Hamlet's comment about an expression based solution, you can have a look at the Dynamic Linq library. It supports lamba expressions defined as strings, which is exactly what you need.
I have an issue that's causing me a lot of headache. I've already googled a solution some days ago, but I didn't found it yet, if one of you guys could help me, it would be great!
I have this method to take the SQL statement for me:
private static string GetClause<T>(IQueryable<T> clause) where T : BaseEntity
{
string snippet = "FROM [dbo].[";
string sql = clause.ToString();
string sqlFirstPart = sql.Substring(sql.IndexOf(snippet));
sqlFirstPart = sqlFirstPart.Replace("AS [Extent1]", "");
sqlFirstPart = sqlFirstPart.Replace("[Extent1].", "");
return sqlFirstPart;
}
But this doesn't work when I try to use some filter (e.g. where), cause it returns me some ""#p_linq_{0}"." instead of the values. I know these are the parameters of my query, but where are they stored?
I use this for batch delete purposes on the EF5 Code First.
If you create a query with a param like this:
var name = "xxx";
var query = ctx.Persons.Where(x => x.FirstName == name);
Then you can get the sql statement and parameters like this:
var oq = ((ObjectQuery<Person>)query);
var trace = oq.ToTraceString();
var p = oq.Parameters;
Use the param name "p_linq_{0}" without the # as an index on p, p["p_linq_{0}"].
I create a complex search query in native SQL. It's basically something like this:
SELECT ID FROM t_Product WHERE Name LIKE #criteria
SELECT publisher, count(*) as number FROM t_Product GROUP BY publisher
It has 2 SELECT statements and I want it to be sent to DB server in one round trip.
But I can't figure out how to achieve this in Nhibernate.
I considered following options but none seems to work
Use CreateMultiQuery, but this only accept HQL, not native SQL
Use CreateSQLQuery, but call to List() only return result for the first SELECT statement
Moving to a stored procedure is not an option since the whole SQL is very dynamic.
We still use Nhibernate 1.2 thus new features in later version couldn't be used either.
Advice are welcome.
Not possible using NH version 1.2
Futures was released in version 2.1 which allows you to do exactly this.
e.g.
var blogs = s.CreateCriteria<Invoice>()
.SetMaxResults(30)
.Future<Invoice>();
var countOfInvoices = s.CreateCriteria<Invoice>()
.SetProjection(Projections.Count(Projections.Id()))
.FutureValue<int>();
So you are going to either upgrade, fall back to ADO.NET and use multiple recordsets or live with what you have! Sorry!
This is really going to be scenario-specific, but if you're stuck with NH Version 1.2, and eliminating the round-trip is your goal, you could consider rewriting this as a single query using a sub-select.
Something along the lines of:
SELECT publisher, count(*) as number,
(SELECT ID FROM t_Product WHERE Name LIKE #criteria) As theId
FROM t_Product GROUP BY publisher
Would work if your subquery only returned a single value.
I don't think that it is possible, because both queries are SELECTs.
You may try a semicolon after the first query, and two line feeds between them, this is required for some databases. I successfully run query-scripts like this. If it runs, use a debugger to see what you get back ...
If this doesn't work, you need separate round trips or switch to HQL / Criteria.
You can use MultiQuery "Hack" like this:
The procudure:
CREATE PROCEDURE [dbo].[proc_Name]
AS BEGIN
SELECT * FROM t_Question where ...
SELECT * FROM t_Question where ........
END
The NHibernate Query Code:
public void ProcdureMultiTableQuery()
{
var session = Session;
var procSQLQuery = session.CreateSQLQuery("exec [proc_Name] ?,?");// prcodure returns two table
procSQLQuery.SetParameter(0, userId);
procSQLQuery.SetParameter(1, page);
procSQLQuery.AddEntity(typeof(Question));
var multiResults = session.CreateMultiQuery()
.Add(procSQLQuery)
// More table your procedure returns,more empty SQL query you should add
.Add(session.CreateSQLQuery(" ").AddEntity(typeof(Question))) // the second table returns Question Model
.List();
if (multiResults == null || multiResults.Count == 0)
{
return;
}
if (multiResults.Count != 2)
{
return;
}
var questions1 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[0]);
var questions2 = ConvertObjectsToArray<Question>((System.Collections.IList)multiResults[1]);
}
static T[] ConvertObjectsToArray<T>(System.Collections.IList objects)
{
if (objects == null || objects.Count == 0)
{
return null;
}
var array = new T[objects.Count];
for (int i = 0; i < array.Length; i++)
{
array[i] = (T)objects[i];
}
return array;
}
I have several methods that use similar linq statements but different enough for them to be in their own methods. So say, for the sake of arguemnt, I had the following linq snippet which is repeated across all methods (the real snippets would be much longer than this):
where su.ObjId == serviceUserId
where cl.StaffMemberId == staffMemberId
If I was working in SQL I could just contatenate the repeated SQL as follows:
private string GetRepeatedSql()
{
return "where su.ObjId = serviceUserId and cl.StaffMemberId = staffMemberId";
}
private void DoSomething()
{
string mySql = "Select * from ...... lots of sql .." + GetRepeatedSql() + ".. some more sql";
}
(Usual health warnings around contatenating SQL string together noted).
Is there something equivalent in Linq? I'm sick of having to make changes in several places - this seems to contravene the DRY principle.
Thanks!
Correct me if I'm wrong but I always thought LINQ statements weren't executed until you actually used them. (Coming from LINQ to NHibernate)
If that is actually the case you could simply just add whatever you need to the existing statement. For example:
var temp=from x in Sometable select x;
Then adding a where clause:
temp = from x in temp where x.ID==1234 select x;
Then order by
temp=from x in temp order by x.ID select x;
I won't lie I have never done it this way but I assume it should work. If someone knows this won't work please explain why. Thanks.
Found this on msdn: http://msdn.microsoft.com/en-us/library/bb397906.aspx
In LINQ the execution of the query is
distinct from the query itself; in
other words you have not retrieved any
data just by creating a query
variable.
So by creating the variable you have not retrieved any data. Although maybe the way I'm doing it above would return data because I am calling from x in temp to change the query.
I do it like this
IQueryable<Publication> pubs = GetPubs();
pubs = ApplySort(pubs, SortBy);
pubs = GetPage(pubs, PageSize, Page);
private IQueryable<Publication> GetPage(IQueryable<Publication> pubs, int PageSize, int Page)
{
return pubs.Skip(PageSize * (Page - 1)).Take(PageSize);
}
private IQueryable<Publication> ApplySort(IQueryable<Publication> pubs, string SortBy)
{
switch (SortBy)
{
case "Latest": return pubs.OrderByDescending(p => p.Posted);
break;
default: return pubs.OrderByDescending(p => p.Posted);
break;
}
}
You can use PredicateBuilder to do this:
The Albahari one here is one I've used recently although there are others around:
http://www.albahari.com/nutshell/predicatebuilder.aspx
I have never used datagrids and such, but today I came across a simple problem and decided to "databind" stuff to finish this faster, however I've found that it doesn't work as I was expecting.
I though that by doing something as simple as:
var q = from cust in dc.Customers
where cust.FirstName == someString
select cust;
var list = new BindingList<Customer>(q.ToList());
return list;
Then using that list in a DataGridView1.DataSource was all that I needed, however, no matter how much I google, I can't find a decent example on how to populate (for add/edit/modify) the results of a single table query into a DataGridView1. Most samples talk about ASP.NET which I lack, this is WinForms.
Any ideas?
I've came across other posts and the GetNewBindingList, but that doesn't seem to change much.
What am I missing (must be obvious)?
You can just bind the IQueryable result to the DataGridView, not sure why you converting it to a BindingList, is there a specific reason for that?
You might have a look at the TableList<T> from this post - based on BindingList<T>, but with hooks into the data-context.
Try this, see the answer of thedugas: unable-to-edit-datagridview-populated-with-results-of-linq-query
Next to a BindingList, it uses a BindingSource. And instead of the MergeEntry class you use your Customer class.
Just bind it.
var q = from cust in dc.Customers
where cust.FirstName == someString
select cust;
DataGridView1.DataSource = q
No need to convert it to list.
string = "12/11/2014"
Try this:
try
{
con_a_refacionesDataContextDataContext con = new con_a_refacionesDataContextDataContext();
BindingSource b = new BindingSource();
b.DataSource = from eq in con.Venta
where eq.fecha_dia == st
select eq;
dataGridView1.DataSource = b;
}
catch
{
}