public ActionResult GenerateReport(FormCollection Form)
{
var type_id = Form["type_id"];
var Start_Date = Form["Start_Date"];
StringBuilder sb = new StringBuilder();
sb.Append("db.contracts.Where(");
if (!type_id.Equals(null))
{
sb.Append("a => a.type_id == type_id");
}
if (!Start_Date.Equals(null))
{
sb.Append("&& a => a.Start_Date == Start_Date");
}
sb.Append(");");
//here I need to run the query!!
return View(cm);
}
How can i execute this LINQ query in C#,
I just want to run the query and get the results..
Please help me...
Thanks in Advance...
EDIT: this answer works with the original question content, how to execute this LINQ expression from a string:
var expression = #"( from a in Assignments
where a.assignmentID == 1 && a.assignmentID == 4 )
select new AssignmentModel
{
Title = a.Title,
Description = a.Description
}).ToList()";
though this answer should work with the generated string in the current question, only you would be injecting db.contracts rather than Assignments as I explain below.
The alternative to using the compilation classes as #GekaLlaur suggests is to compile the string into an Expression tree, which is possibly more appropriate here as you're compiling LINQ expressions.
The solution found in this SO post (Chosen Solution) looks as though it should work out of the box for you, only using var p = Expression.Parameter(typeof(List<AssignmentModel>), "Assignments"); to describe your parameter. I would test it with your specific example but I don't already have the libraries (linked here).
Don't do this. Use a Predicate Builder instead!
Here is a great implementation from C# in a nutshell:
http://www.albahari.com/nutshell/predicatebuilder.aspx
The predicate builder uses a free library called linqkit:
http://www.albahari.com/nutshell/linqkit.aspx
Here is another SO question that addresses this topic and how the whole thing works
How does PredicateBuilder work
Related
I'm trying to convert some JS into C# and i got to this piece but cant figure out what a C# equivalent would be. Hoping someone can point me in the right direction?
I just need help with the contents of these two functions. The $iterator is coded in another spot but im guessing that the C# version of the following code doesnt need it. If you need me to add it, i can.
The context these functions are being called is:
var centers = Lambda.array(Lambda.map(this.hexes,function(hex) {
return me.hexToCenter(hex);
}));
And the functions are:
var Lambda = function() { }
Lambda.array = function(it) {
var a = new Array();
var $it0 = $iterator(it)();
while( $it0.hasNext() ) {
var i = $it0.next();
a.push(i);
}
return a;
}
Lambda.map = function(it,f) {
var l = new List();
var $it0 = $iterator(it)();
while( $it0.hasNext() ) {
var x = $it0.next();
l.add(f(x));
}
return l;
}
You don't really need your own map and array methods. There is already the same functionality available, you just have to add using System.Linq; at the top of your file and you'll be able to use both Select, which is a projection method and ToArray which created an array from your collection. They are both extension methods set on IEnumerable<T>, so you can use them on almost any collection.
var centers = hexes.Select(x => me.hexToCenter(x)).ToArray();
is an equivalent of you JavaScript code:
var centers = Lambda.array(Lambda.map(this.hexes,function(hex) {
return me.hexToCenter(hex);
}));
This looks like a fairly simple C# lambda:
var centers = this.hexes.Select(hex => me.hexToCenter(hex)).ToList();
Select and ToList extension methods are provided by LINQ - you need to add using System.Linq to use them.
You probably want to go the LINQ route here.
Your map is equivalent to LINQ's Select, e.g.
var centers = this.hexes.Select(hex => me.hexToCenter(hex)).ToArray();
The expression hex => me.hexToCenter(hex) is a lambda expression in C#, which Select uses to project this.hexes into your desired form.
ToArray() is equivalent to your Lambda.array call.
101 LINQ Samples in C# is a great resource for examples on using LINQ.
note most of the 101 samples use the query syntax as opposed to the functional syntax I've used above. They are roughly equivalent for simple cases, but being comfortable with the functional syntax shouldn't be a problem for you, coming from JS background.
We are using Xamarin with SQLiteNet as ORM.
In our data layer class we have the method below.
filter = ri => ri.ItemVersioniId == itemVersionId;
The method is getting the records matching the Id. If the lambda expression is hardcoded, instead of using the "filter" parameter it is much faster... even though it is the same logic.
We would to be able to pass the filter as a parameter but still get a good performance. Any advise?
public virtual List<ResourceItem> GetResourceItems (string itemVersionId, Func<ResourceItem,bool> filter ){
//var t = db.Table<ResourceItem> ().Where (ri => ri.ItemVersionId == itemVersionId); --* this line is 10 times faster
var t = db.Table<ResourceItem> ().Where (filter); --* this line is 10 times slower
return new List<ResourceItem> (t);
}
I'm not sure because it is xamarin specific, but i suggest to use Expression instead of Func.
Expression<Func<ResourceItem,bool>> filter =
ri => ri.ItemVersioniId == itemVersionId;
public virtual List<ResourceItem> GetResourceItems
(string itemVersionId, Expression<Func<ResourceItem,bool>> filter )
{
return db.Table<ResourceItem> ().Where (filter).ToList();
}
I would advise hard coding it. Here is why, but first let me qualify this by saying I am speculating - I have no experience with SQLiteNet - this based on some general, rudimentary knowledge on how LINQ Prodivers work.
When you have it hard coded the lambda expression is converted to SQL at compile time. When you set it to a delegate, it could be a LINQ to Objects query, there is no way to know at compile time that your LINQ Provider can convert that to a SQL statement. Instead this work occurs at runtime and as a result the performance suffers greatly.
I have to query a repository where column a = {myvalue} and column b has any value in a collection.
Here's what I have:
Application[] applicationCollection = GetAllApplications();
var result = repo.GetAll(r => r.Email == myEmail && r.Application.In(applicationCollection));
I can't figure out how to write the "in" part...
Preferrably links to how to do this would be best, so I can learn it, as opposed to just getting the answer :). Thanks all.
(I'm sure this is a repeat question, but my Google/search skills are obviously poor.)
The SQL idea of item in collection is written in C# (including LINQ) as collection.Contains(item). In your example, this might be:
var result = repo.GetAll(r => r.Email == myEmail &&
applicationCollection.Contains(r.Application));
ApplicationCollection.Contains(r.Application)
Use .Contains(collection) instead of in. Here's a link since you wanted one.
If you want to write it the way you've shown, you can write this extension method:
public static bool In<T>(this T item, IEnumerable<T> set)
{
return set.Contains(item);
}
And then use it exactly like you did in your question:
Application[] applicationCollection = GetAllApplications();
var result = repo.GetAll(r =>
r.Email == myEmail &&
r.Application.In(applicationCollection));
This will work fine if you're only working with in-memory sets. If you're doing something like LINQ-to-SQL, however, this won't be compatible.
Note: I'm not trying to imply that this extension method might be a good idea to use - I'm just saying it's possible to write one like that.
How do i find out if a string is containing the exact word i am looking for?
example: "this is my text"; word looking for: "text"; found: yes.
example: "these are my texts"; word looking for: "text"; found: no.
it's inside a linq to entities query, so regex won't work?
Edit:
This is more or less what i'm doing now and i want to replace it by a function that returns only when it's the exact match.
using (Model.Manager ctx = new Model.Manager())
{
var result = from p in ctx.Companies where p.Name.Contains(workLookingFor) select p;
}
Solution so far:
I could use .Contains() on my DB and use RegEx on the results pulled from the DB. Since the exact matches are always inside the broader results from .Contains() (which i still need anyways) this could be a good solution
This works for me. It's not perfect but might help.
public static bool matchWholeWord(string test, string search)
{
var index = test.IndexOf(search);
if (index == -1)
return false;
var after = index + search.Length;
if (after == test.Length)
return true;
return !char.IsLetterOrDigit(test[after]);
}
in your code:
using (Model.Manager ctx = new Model.Manager())
{
var result = from p in ctx.Companies
where matchWholeWord(p.Name, workLookingFor)
select p;
}
There isn't an easy way. You have three options
run your query, then do the pattern matching on the client
use SQL Fulltext Search engine
add a CLR function to the database that lets you do regex matching
I had to use something similar to this to implement a search algorithm using LINQ recently. I found the MSDN article on combining LINQ and Regular Expressions to be useful, along with a regular expression that used the space marker to identify whitespace. By constructing the regex with my search parameters and combining that into my LINQ expression, I ended up with what I needed.
I'm trying to implement method Find that searches the database.
I forgot to mention that I'm using Postgresql, so I can't use built in LINQ to SQL.
I want it to be like that:
var user = User.Find(a => a.LastName == "Brown");
Like it's done in List class. But when I go to List's source code (thanks, Reflector), I see this:
public T Find(Predicate<T> match)
{
if (match == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
for (int i = 0; i < this._size; i++)
{
if (match(this._items[i]))
{
return this._items[i];
}
}
return default(T);
}
How can I implement this thing? I need to get those parameters to make the search.
Solution
Okay, I understood now that I need to do LINQ to SQL to do all this good expressions stuff, otherwise I'd have to spend a lot of time reimplementeing the wheel.
Since I can't use LINQ to SQL, I implemented this easy method:
public static User Find(User match, string orderBy = "")
{
string query = "";
if (!String.IsNullOrEmpty(match.FirstName)) query += "first_name='" + match.FirstName + "'";
if (!String.IsNullOrEmpty(match.LastName)) query += "last_name='" + match.LastName+ "'";
return Find(query + (!String.IsNullOrEmpty(orderBy) ? orderBy : ""));
}
This is how to use it:
var user = User.Find(new User { FirstName = "Bob", LastName = "Brown" });
Your method should accept Expression<Func<User>>.
This will give you expression tree instead of delegate which you can analyze and serialize to SQL or convert to any other API call your database have.
If you want everything to be generic, you may wish to go on with implementing IQueryable interface. Useful information can be found here: LINQ Tips: Implementing IQueryable Provider
Although for a simple scenario I would suggest not to complicate everything and stick with using Expression Trees and returning plain IEnumerable<T> or even List<T>.
For your case first version of code could look like this:
public IEnumerable<T> Get(Expression<Func<T, bool>> condition)
{
if (condition.Body.NodeType == ExpressionType.Equal)
{
var equalityExpression = ((BinaryExpression)condition.Body);
var column = ((MemberExpression)equalityExpression.Left).Member.Name;
var value = ((ConstantExpression)equalityExpression.Right).Value;
var table = typeof(T).Name;
var sql = string.Format("select * from {0} where {1} = '{2}'", table, column, value);
return ExecuteSelect(sql);
}
return Enumerable.Empty<T>();
}
And it's complexity grows fast when you want to handle new and new scenarios so make sure you have reliable unit tests for each scenario.
C# Samples for Visual Studio 2008 contain ExpressionTreeVisualizer that will help you to dig into Expression Trees more easily to understand how to extract information you need from it.
And of course, if you can stick with using existing implementation of LINQ, I would suggest to do it. There are Linq to SQL for SQL Server databases, Linq to Entities for many different databases, Linq to NHibernate for NHbernate projects.
Many other LINQ providers can be found here: Link to Everything: A List of LINQ Providers. Amount of work to implement LINQ provider is not trivial so it's a good idea to reuse tested and supported solution.
Exactly the same way. Just replace this._items with your users collection.
Also replace the type parameter T with the type User.
A lambda expression in source code can be converted to either a compiled executable delegate or an expression tree upon compilation. Usually we associate lambda's with delegates but in your case since you say you want access to the parameters (in this case I assume you mean LastName and "Brown" then you want an expression tree.
Once you have an expression tree, you can parse it to see exactly what it is an translate it to whatever you actually need to do.
Here are a few questions about expression trees.
Expression trees for dummies?
Bit Curious to understand Expression Tree in .NET
Sounds like you're definitely reinventing a very complicated wheel though. I'm sure it'll be a useful learning experience, but you should look into LINQ to Entities or LINQ to SQL for real-world programming.
Maybe I just haven't understood the question, but there's already a method for doing what you want: Enumerable.Where.
If you need to find a single element then use SingleOrDefault or FirstOrDefault instead.
You could do it something like this:
public static IEnumerable<User> Find(Predicate<User> match)
{
//I'm not sure of the name
using (var cn = new NpgsqlConnection("..your connection string..") )
using (var cmd = new NpgsqlCommand("SELECT * FROM Users", cn))
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
var user = BuildUserObjectFromIDataRecord(rdr);
if (match(user)) yield return user;
}
}
}
And then you can call it like this
var users = User.Find(a => a.LastName == "Brown");
Note that this returns any number of users, you still have to implement the BuildUserObjectFromIDataRecord() function, and that it will always want to iterate over the entire users table. But it gives you the exact semantics you want.
Okay, I understood now that I need to do LINQ to SQL to do all this good expressions stuff, otherwise I'd have to spend a lot of time reimplementeing the wheel.
Since I can't use LINQ to SQL, I implemented this easy method:
public static User Find(User match, string orderBy = "")
{
string query = "";
if (!String.IsNullOrEmpty(match.FirstName)) query += "first_name='" + match.FirstName + "'";
if (!String.IsNullOrEmpty(match.LastName)) query += "last_name='" + match.LastName+ "'";
return Find(query + (!String.IsNullOrEmpty(orderBy) ? orderBy : ""));
}
This is how to use it:
var user = User.Find(new User { FirstName = "Bob", LastName = "Brown" });
One way would be to create an anonymous delegate, like so:
Predicate<User> Finder = delegate(User user)
{
return user.LastName == "Brown";
}
var User = User.Find(Finder);