I have the following linq:
var recprec = (from rc in db.tblTrucks
where rc.ID == recid
select rc
}).FirstOrDefault();
How do I intialize recprec and then fill it in late. For example with a string we can do something like String xyz and then use that string later.
I need to do the same with var recprec.
I tried doing
Object recprec = null;
recprec = (from rc in db.tblTrucks
where rc.ID == recid
select rc
}).FirstOrDefault();
I am doing this as I need to use recprec in a number of different places in my program. If I keep it as var recprec... it goes out of scope so like to declare it at top where it is in scope througout my program.
In your specific case, your LINQ query will return whatever tblTrucks contains. If it's a DataTable, your query will return a single DataRow. If it's a List<Truck>, it'll return a single Truck. You just have to know what's contained within the collection you're querying.
Related
I want to get list of records from an entity model (I'm using EF version 5) with a particular accountID. I'm being supplied with the tableName string (this has to be dynamic) and the accountID. I'm trying the following 2 methods but none of them is working (giving me errors on the IQueryable object 'table':
PropertyInfo info = _db.GetType().GetProperty(tableName);
IQueryable table = info.GetValue(_db, null) as IQueryable;
var query = table.Where(t => t.AccountID == accID)
.Select(t => t);
List <object> recList = ( from records in table
where records.AccountID == accID
select records).ToList<object>();
The var query = table.Where(....).Select(...) is the correct move as it allows reflection for the query builder at runtime. However, t.AccountID is an error because of the type of t remains unknown.
I've previously used a similar approach in LINQ to SQL, using System.Linq.Expressions.Expression, e.g.:
// NOT TESTED
var table=context.GetTable(dynamicTableName);
var theT=table.Experssion; // actually, I forget. DynamicExpression or MemberBinding? or
var theField=Expression.Field(theT, "AccountID"); // or dynamic name
var query=table.Where(Expression.Equal(theField, accID);
var recList=query.ToList<object>();
If your object has a common interface there is a simpler syntax:
IQueryable<MyInterface> table = context.GetTable("table") as IQueryable<MyInterface>;
var recList=from r in table
where table.AccountID == ac // if your AccountID is on MyInterface
select table;
If you only have a few tables to support, you could do this as well:
IQueryable<MyInterface> table;
if("table1"==tableName)
table=_db.table1
elseif("table2"==tableName)
table=_db.table2
elseif("table3"==tableName)
table=_db.table3
else
throw exception
I built a DynamicRepository for a project I am working on. It uses generic methods exposed through EF along with dynamic linq. It might be helpful to look at that source code here:
https://dynamicmvc.codeplex.com/SourceControl/latest#DynamicMVC/DynamicMVC/Data/DynamicRepository.cs
You can query the entity framework metadata workspace to get the type for a given table name. This link might help:
Get Tables and Relationships
I am trying to return the results of a query into a List object, however the following code, as I normally use, does not work. Still relatively new to Linq, can someone explain the correct syntax/what's going on? This will work if I change the data type of productTraining to var...
List<AgentProductTraining> productTraining = new List<AgentProductTraining>();
productTraining = from records in db.CourseToProduct
where records.CourseCode == course.CourseCode
select records;
Select() and Where() will return IQueryable<T>, not List<T>. You've got to convert it to a List<T> - which actually executes the query (instead of just preparing it).
You just need to call ToList() at the end of the query. For example:
// There's no need to declare the variable separately...
List<AgentProductTraining> productTraining = (from records in db.CourseToProduct
where records.CourseCode == course.CourseCode
select records).ToList();
Personally I wouldn't use a query expression though, when all you're doing is a single Where clause:
// Changed to var just for convenience - the type is still List<AgentProductTraining>
var productTraining = db.CourseToProduct
.Where(records => records.CourseCode == course.CourseCode)
.ToList();
I m trying to select a column's value from a datatable based on conditions.
var results = from DataRow myRow in dtCallBack.AsEnumerable()
where myRow.Field<DateTime>(1) == startDateTime
&& myRow.Field<int>(0) == callBackID
select myRow.Field<int>(3);
My datatable contains 4 columns ID,Date1,Date2,IntVal
I want to convert the variable results to int. (I want to return the column 4 IntVal)
var results = (from DataRow myRow in dtCallBack.AsEnumerable
where myRow.Field<DateTime>(1) == startDateTime
&& myRow.Field<int>(0) == callBackID
select myRow.Field<int>(3)).SingleOrDefault();
Well you've currently got an IEnumerable<int> by the looks of it. So which of those results do you want? What do you want to happen if there aren't any results?
If you're confident there's only a single result, you can use:
var result = results.Single();
If you want the first result or 0 if there aren't any, you could use
var result = results.FirstOrDefault();
If you want the first result and an exception if there aren't any, you could use
var result = results.First();
Basically there are lots of options, and you'll need to clarify your requirements before we can really give you a more concrete answer.
I'm very new to Linq, I can find multi-line data reading examples everywhere (by using foreach()), but what is the correct way of reading a single line of data? Like a classic Product Detail page.
Below is what I tried:
var q = from c in db.Products
where c.ProductId == ProductId
select new { c.ProductName, c.ProductDescription, c.ProductPrice, c.ProductDate };
string strProductName = q.First().ProductName.ToString();
string strProductDescription = q.First().ProductDescription.ToString();
string strProductPrice = q.First().ProductPrice.ToString();
string strProductDate = q.First().ProductDate.ToString();
The code looks good to me, but when I see the actual SQL expressions generated by using SQL Profiler, it makes me scared! The program executed four Sql expressions and they are exactly the same!
Because I'm reading four columns from a single line. I think I must did something wrong, so I was wondering what is the right way of doing this?
Thanks!
Using the First() extension method would throw the System.InvalidOperationException when no element in a sequence satisfies a specified condition.
If you use the FirstOrDefault() extension method, you can test against the returned object to see if it's null or not.
FirstOrDefault returns the first element of a sequence, or a default value if the sequence contains no elements; in this case the default value of a Product should be null. Attempting to access the properties on this null object will throw ArgumentNullException
var q = (from c in db.Products
where c.ProductId == ProductId
select new { c.ProductName, c.ProductDescription, c.ProductPrice, c.ProductDate }).FirstOrDefault();
if (q != null)
{
string strProductName = q.ProductName;
string strProductDescription = q.ProductDescription;
string strProductPrice = q.ProductPrice;
string strProductDate = q.ProductDate;
}
Also, you shouldn't have to cast each Property ToString() if you're object model is setup correctly. ProductName, ProductDescription, etc.. should already be a string.
The reason you're getting 4 separate sql queries, is because each time you call q.First().<PropertyHere> linq is generating a new Query.
var q = (from c in db.Products
where c.ProductId == ProductId
select new { c.ProductName, c.ProductDescription, c.ProductPrice, c.ProductDate }
).First ();
string strProductName = q.ProductName.ToString();
string strProductDescription = q.ProductDescription.ToString();
string strProductPrice = q.ProductPrice.ToString();
string strProductDate = q.ProductDate.ToString();
I have a combo box in Silverlight. It has a collection of values built out of the properties of one of my LINQ-to-SQL objects (ie Name, Address, Age, etc...). I would like to filter my results based off the value selected in a combo box.
Example: Say I want everyone with a last name "Smith". I'd select 'Last Name' from the drop down list and enter smith into a textbox control. Normally I would write a LINQ query similar to...
var query = from p in collection where p.LastName == textbox.Text select p;
Is it possible to decide the property dynamically, maybe using Reflection? Something like
var query = from p in collection where p.(DropDownValue) == textbox.Text select p;
Assuming:
public class Person
{
public string LastName { get; set; }
}
IQueryable<Person> collection;
your query:
var query =
from p in collection
where p.LastName == textBox.Text
select p;
means the same as:
var query = collection.Where(p => p.LastName == textBox.Text);
which the compiler translates from an extension method to:
var query = Queryable.Where(collection, p => p.LastName == textBox.Text);
The second parameter of Queryable.Where is an Expression<Func<Person, bool>>. The compiler understands the Expression<> type and generates code to build an expression tree representing the lambda:
using System.Linq.Expressions;
var query = Queryable.Where(
collection,
Expression.Lambda<Func<Person, bool>>(
Expression.Equal(
Expression.MakeMemberAccess(
Expression.Parameter(typeof(Person), "p"),
typeof(Person).GetProperty("LastName")),
Expression.MakeMemberAccess(
Expression.Constant(textBox),
typeof(TextBox).GetProperty("Text"))),
Expression.Parameter(typeof(Person), "p"));
That is what the query syntax means.
You are free to call these methods yourself. To change the compared property, replace this:
typeof(Person).GetProperty("LastName")
with:
typeof(Person).GetProperty(dropDown.SelectedValue);
Scott Guthrie has a short series on dyamically built LINQ to SQL queries:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
That's the easy way...then there's another way that's a bit more involved:
http://www.albahari.com/nutshell/predicatebuilder.aspx
You can also use the library I created: http://tomasp.net/blog/dynamic-linq-queries.aspx. You would store the properties in ComboBox as lambda expressions and then just write:
var f = (Expression<Func<Product, string>>)comboBox.SelectedValue;
var query =
from p in collection
where f.Expand(textBox.Text)
select p;