I cannot use LinqToSql in my project so I'm implementing something like that. I have an object where I need to compare values :
obj.Where(w=> w.Name == "NAME");
Method Where looks like this :
Where(Expression<Func<T, bool>> expression)
I already know how to get a property name but I nees to ge following information from the expression:
Operator used in expression (==, >=, <=)
Value to which I'm comparing original value
So finally I can build an SQL select query.
EXAMPLE
obj.Where(w=> w.Name == "NAME");
returns
WHERE Name = 'NAME'
Thanks for your help,
B.
You can traverse expression tree, for example using a visitor like in this example. But before developing custom SQL query generator I'd definitely consider using an existing one - the task is really complicated. Entity Framework, for example.
Related
I have the following structure that I wan't to query using Linq, specifically Linq to Entities (Enitity Framework).
Table1: RouteMeta
Table2: SitePage
Multiple SitePages can link to the same RouteMeta.
I'm querying the Route Meta to select a number of rows. I'm using a generic repository, currently like this:
return r.Find().ToList();
There's nothing special about it - the Find method accepts an optional linq expression, so I could do something like this:
return r.Find(x => x.Status=1).ToList();
However, what I actually want to do is to select rows from RouteMeta where at least one linked row exists in SitePages with a property IsPublished = true.
return r.Find(x => x.SitePages("where y => y.IsPublished = true");
Obviously, the above isn't correct, I'm just trying to explain the scenario better.
Any advice appreciated.
try something like
return r.Find(x=>x.Sitepages.Any(y=>y.Published))?
I'd also suggesting using a profiler if possible to check that this translates properly into SQL. It probably should do but it depends on how your repository works.
I am trying to find a way to create the Linq Expression tree for a sub-query in-clause.
SELECT * FROM x WHERE X.Id IN (SELECT XId FROM Y)
Say I have this query, I need a way to create the System.Linq.Expression of the where clause. I have a generic repository base solution for numerous Entities and I am creating the expression tree dynamically for other filters and I would like to add this to the already created expression tree.
I know I can do something like below, but it isn't generic enough.
var xIds = Y.Select(x => x.XId).ToList();
var final = X.Where(x => xIds.Contains(x.Id)).ToList();
But I need Expression tree that this would create.
I played around with this link: Creating a Linq expression dynamically containing a subquery and it doesn't seem to work. I might be missing something though, been staring at this for a while.
Thanks!
I have some LINQ query (or IQueryable<T> object based on LINQ query) and want to get some unique string based on this query.
I have, for example:
var someValue = 10;
var query = (from i in db.Customers
where i.Id == someValue
select i).AsQueryable();
I should get something like this:
"from i in db.Customers where i.Id == 10"
I am trying to use Expression object and play with it but I can not get generic approach to get string with exact parameters values.
E.g.:
public string GetKey<T>(IQueryable<T> query)
{
...
return unique_string;
}
Note that different parameters values for the same LINQ query should provide different strings.
Thanks in advance.
I strongly suspect that this is simply not going to work. Aside from anything else, if you have to use AsQueryable (i.e. if your original query is over IEnumerable<T> then the compiler will have used delegates instead of expression trees to start with.
If it's a pure IQuerable<T> all the way, you could try using query.Expression.ToString(), but frankly it's not something I'd want to rely on.
Solved this issue with Expression Tree Serialization with some improvements for getting exact values of passed parameters. It provides a big but unique XML file based on IQueryable objects.
I'm writing a little library to help building SQL requests (only doing SELECTs for the moment) but I'm not satisfied with an aspect of the syntax, here's an exemple to explain:
var db = FluentDb.WithConnectionString("SqlCeTest");
var query = db.From("Customers")
.Where(FS.Col("Age") > 18 & FS.Col("Name").StartsWith("L"))
.OrderBy("BirthDate")
.Select("Name", "Age", "BirthDate");
var customers = query.ToList((r) => new
{
Name = r.Get<string>("Name"),
Age = r.Get<int>("Age"),
BirthDate = r.Get<DateTime?>("BirtDate")
});
The part I'd like to improve is the FS.Col("ColumnName"), it's supposed to stand for FluentSql.Column (return a new FluentColumn(columnName)), but I find it a bit long in that context, what I'd really like is to be able to use just Col("ColumnName")...
Do anybody see a trick I could use to achieve that, or another syntax idea?
My ideas:
Extension method on string: Where("Name".Col() == "Jon")
Lambda expression with factory object using indexer: .Where(c => c["Name"] == "Jon")
Anyone see something better/shorter/nicer?
Edit:
my second idea looks good but there's a downside if i use it in another context:
I sometime need to use FluentColumns in Select (or OrderBy, or GroupBy) statements like that:
query.Select(FS.Col("Name").As("Customer"), FS.Col("OrderId").Count().As("OrdersCount"));
I would have to repeat the 'c => ' for each column...
A twist on your second option (which is pretty good) would be to use a dynamic expandoobject in the lambda instead of a string indexer.
http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx
Just for information, I decided to go with an indexer syntax on the FluentDb instance:
db["Customer", "AddressId"] mean column AddressId of table Customer,
an alternative syntax is available: db["Customer"]["AddressId"]
So in the end, it's gonna be (I still need to find a trick to make the Column declaration without table nice):
.Where(db["Customer", "Name"] == "Jon")
How can I do something like this:
customers.where(c=>c.Name **like** "john");
I know this isn't possible but I was wondering how can I have something similar.
customers.Where(c => c.Name.Contains("john"));
If you are targeting LINQ to SQL, use SqlMethods.Like:
customers.Where(c => SqlMethods.Like(c.Name, "%john%"));
Explanation:
The compiler will generate an expression tree from the statement above. Since LIKE is a SQL specific construct and not common to all LINQ Query providers, the SqlMethods class and its members are used as a "hint" for the expression compiler (compiles expression trees to SQL) to emit a LIKE statement.
The first thought that comes to mind is Regex.IsMatch.
This would come closest to providing the kind of functionality you get from LIKE; for instance with it you could do this:
var matches = people.Where(p => Regex.IsMatch(p.Name, "A.*[mn]"));
foreach (Person match in matches)
{
Console.WriteLine(match.Name);
}
And get output like this:
Adam
Aaron
Aidan
Going with string.Contains as others have suggested is almost certainly preferable if your intention is simply to look for a specific substring within Name.
using System.Data.Linq.SqlClient;
...
customers.where(c=>SqlMethods.Like(c.Name, "john"));
Use Regex.IsMatch in your where statement or for a more simpler version without wildcards etc.:
customers.where(c=>c.Name.Contains("john"));
Here is my code :
string s="somethings";
customers.Where(c => c.Name != null && c.Name.ToLower().Contains(s.ToLower()));
Somethings like that.