Using Nihibernate with system dynamic linq for Query<T> - mysql

I am trying to use system.dynamic.linq to create dynamic sorting.
this, is the query that I use:
var query = dalSession.Query<T>().AsQueryable();
var res = (from x in query orderby "x.FirstName" select x)
this is the mysql output:
select
affiliate0_.id as id0_,
affiliate0_.first_name as first6_0_,
from affiliate affiliate0_ order by 'x.FirstName' //FirstName as well
So you can see that the output went to the mysql query is the direct string, and not its reflection, ('x.FirstName') or ('FirstName').
This has no meaning in mysql context, it looks like I need order by affiliate0_.first_name.
Is there anyway to provide the Nhibernate the member itself? So the compiled query will be done normally?

You have to remove the " from you requiry. "x.FirstName" is seen as a string and translated to a sql string.

The "x" has no meaning inside the dynamic string.
Remove the x. (i.e. leave just "FirstName") and it should work.
Using a method call instead of the query comprehension syntax, you'd get:
var res = query.Orderby("FirstName")

Did you try it as follows (as Diego suggested)?
(from x in query select x).OrderBy("FirstName")
Because I think the dynamic linq orderby extension method is not executed when you use (x => "FirstName")
Otherwise try this:
(from x in query select x).OrderBy("it.FirstName")
BTW I renamed the OrderBy method in Dynamic.cs to DynamicOrderBy because I had some situations where the not dynamic linq OrderBy method was executed too:
public static IQueryable<T> DynamicOrderBy<T>(this IQueryable<T> source, string ordering, params object[] values) and use that one instead:
(from x in query select x).DynamicOrderBy("FirstName")

var param = Expression.Parameter("x");
var prop = Expression.Property(param, "FirstName");
var lambda = Expression.Lambda<Func<User, string>>(prop, param);
query.Orderby(lambda);

Related

LINQ for SQL statement that returns single scalar value

I want to execute the following select:
SELECT 0 as Value
What is the correlating syntax in LINQ for SQL?
Edit
I want to use the correlating LINQ for SQL statement in a Concat() call like this
var c = (from a in mytable select a.Value).Concat(select 0).Sum();
As you can see, Concat(select 0) obviously doesn't compile. Any ideas?
Edit 2
David suggested to use a simple collection instead. I've tried
private decimal[] mZeroDecimals = new[] { 0.0m };
...
public void MyFunction()
{
var c = (from a in mytable select a.Value).Concat(mZeroDecimals).Sum();
...
but it throws an exception Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.
You're not actually querying anything, so there is no LINQ involved. You're just creating an anonymous object with a single property called Value:
var obj = new { Value = 0 };
Edit: Based on your comment, it sounds like you want this object in a collection. That doesn't make it a LINQ query (since you're still not querying anything), but you can declare a collection just as easily as a single object. Something like this:
var coll = new[] { new { Value = 0 } };
Since this is a collection, it can be used with any of the enumerable extension methods that LINQ uses, which sounds like what you're trying to do.

How to aggregate IEnumerable<string> to string using Linq Aggregate function

I have Ienumerable<string> collection that I want to concatenate into a single string with delimitor ;
for instance {"One","Two","Three"} -> "One;Two;Three;"
is it possible to do using the following function?
List<string> list = new List<string>(){"One","Two","Three"};
list.Aggregate<String>((x,y) => x + String.Format("{0};",y));
I have tried also this code:
list.Aggregate<String>((x,y) => String.Format("{0};{1}",x,y));
both samples didn't work.
EDIT: I see that it is not possible to do what I wanted using Linq-2-sql or Aggregate function in Linq-2-sql.
http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/dac496c0-5b37-43ba-a499-bb8eff178706/
EDIT2: the workaround I used is to go over the items returned by the original linq query...and copies them to a new list and do the join as suggested in the answers below on a linq object and not linq-2-sql object.
You can just use String.Join for this. If you're using .NET4 then you can use the overload that takes an IEnumerable<string> directly:
string joined = string.Join(";", list);
If you're using an older version of the framework then you'll need to use the overload that takes a string[] array instead, converting your collection to an array first if necessary:
string joined = string.Join(";", list.ToArray());
EDIT...
Of course, if you really want to use Aggregate for some reason then there's nothing stopping you. If so, it's usually recommended to build your string using a StringBuilder rather than multiple string allocations:
string joined = list.Aggregate(new StringBuilder(),
(sb, s) => sb.Append(s).Append(';'),
sb => (sb.Length > 0) ? sb.ToString(0, sb.Length - 1)
: "");
You can do it using below code
list.Aggregate((i, j) => i + ";" + j);
You'll need to provide an initializer, otherwise the first element will not have a ; added to it:
list.Aggregate<String>("", (x,y) => x + String.Format("{0};",y));

LINQ to SQL: Reuse lambda expression

I stumbled over some strange LINQ to SQL behaviour - can anybody shed some light on this?
I want to define a lambda expression and use it in my LINQ statement. The following code works fine:
[...]
Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table1s.Where(lambda);
[...]
But when I try to use my lambda expression in a statement on an associated table
[...]
Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table2s.Where(x => x.Table1s.Any(lambda));
[...]
I get an exception:
Unsupported overload used for query operator 'Any'.
But, and this I don't get: It works fine when I put my lambda directly into the query:
[...]
var result = dataContext.Table2s.Where(x => x.Table1s.Any(y => y.Id > 1000));
[...]
WHY?!
Thanks.
Okay, here's the deal: dataContext.Table1s is of type IQueryable<T>. IQueryable<T> defines Where and Any methods that take a predicate of type Expression<Func<T, bool>>. The Expression<> wrapper is critical, as this is what allows LINQ to SQL to translate your lambda expression to SQL and execute it on the database server.
However, IQueryable<T> also includes IEnumerable<T>. IEnumerable<T> also defines Where and Any methods, but the IEnumerable version takes a predicate of type Func<T, bool>. Because this is a compiled function and not an expression, it can't be translated to SQL. As a result, this code...
Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table1s.Where(lambda);
...will pull EVERY record out of Table1s into memory, and then filter the records in memory. It works, but it's really bad news if your table is large.
Func<Table1, bool> lambda = x => x.Id > 1000;
var result = dataContext.Table2s.Where(x => x.Table1s.Any(lambda));
This version has two lambda expressions. The second one, being passed directly into Where, is an Expression that includes a reference to a Func. You can't mix the two, and the error message you're getting is telling you that the call to Any is expecting an Expression but you're passing in a Func.
var result = dataContext.Table2s.Where(x => x.Table1s.Any(y => y.Id > 1000));
In this version, your inner lambda is automatically being converted to an Expression because that's the only choice if you want your code to be transformed into SQL by LINQ to SQL. In the other cases, you're forcing the lambda to be a Func instead of an Expression - in this case you're not, so it works.
What's the solution? It's actually pretty simple:
Expression<Func<Table1, bool>> lambda = x => x.Id > 1000;
Does Table1 refer to the same namespace? In the first example you're querying against the Table1 objects that are directly under dataContext, in the second example you're querying against the Table1 objects that is a property of the Table2 objects, and in the last example you're using a anonymous function which fix the issue.
I would look up the type of the Table1 objects that is a property of a Table2 object and compare it to a Table1 object that is connected directly to the dataContext. My guess is that they differ and your lambda expression is using the type of the object that is connected to the dataContext.

How do I get a list of column name using Linq to Sql

How can i dynamically get a list of Column names based on my query model below using Linq to SQL. Example of query below.
public void GetColumnName()
{
var db = from ci in Db.CatalogItems
join i in Items
on ci.ItemId equals i.ItemId
select i;
}
I'm new to the concept of Reflection. How do I go about doing that with the model query above?
use reflection on db? (get the fields)
from rec in Db.syscolumns ....

Linq: Simple Boolean function returns linq Exception

I have a Linq query that looks something like this:
var query = from x in table where SomeFunctionReturnsBool() select;
private bool SomeFunctionReturnsBool()
{
return true;
}
This returns and exception that says "SomeFunctionReturnsBool has no supported translation to SQL". I get that this is because it wants to treat "SomeFunctionReturnsBool" as an expression to evaluate as SQL, but it can't.
Although this Linq query isn't complicated, the real ones are. How can I accomplish what I'm trying to do here, which is to break out pieces of the query to hopefully make it more readable?
Jeff
UPDATE
Good answers. I am trying now to work with expressions instead, but this code gets me "cannot resolve method Where(lambda expression)":
var query = from x in table where SomeFunctionReturnsBool() select x;
private Expression<Func<EligibilityTempTable, bool>> SomeFunctionReturnsBool
{
return (x) => true;
}
Another way is to use Expression<Func<YourType, bool>> predicate...
var query = from x in table where SomeFunctionReturnsBool() select;
Edit: I don't usually do it the way I've shown above... I was just getting that from the code above. Here is the way I usually implement it. Because then you can tack on additional Enumerable methods or comment them out during debugging.
var results = table.Where(SomeFunctionReturnsBool())
.OrderBy(yt => yt.YourProperty)
//.Skip(pageCount * pageSize) //Just showing how you can easily comment out parts...
//.Take(pageSize)
.ToList(); //Finally executes the query...
private Expression<Func<YourType, boo>> SomeFunctionReturnsBool()
{
return (YourType yt) => yt.YourProperty.StartsWith("a")
&& yt.YourOtherProperty == true;
}
I prefer to use the PredicateBuilder which allows you to build an expression to be used in your Where...
You can do this in LINQ-to-SQL by creating a UDF mapped to the data-context; this involves writing TSQL, and use ctx.SomeFunctionblah(...).
The alternative is to work with expression trees - for example, it could be:
Expression<Func<Customer, bool>> SomeFunc() {
return c => true; // or whatever
}
and use .Where(SomeFunc()) - is that close enough? You can't use the query syntax in this case, but it gets the job done...
Added dodgy Where method to show how you might use it in query syntax. I don't suggest this is fantastic, but you might find it handy.
using System;
using System.Linq;
using System.Linq.Expressions;
static class Program
{
static void Main()
{
using (var ctx = new NorthwindDataContext())
{
ctx.Log = Console.Out;
// fluent API
var qry = ctx.Customers.Where(SomeFunc("a"));
Console.WriteLine(qry.Count());
// custom Where - purely for illustration
qry = from c in ctx.Customers
where SomeFunc("a")
select c;
Console.WriteLine(qry.Count());
}
}
static IQueryable<T> Where<T>(this IQueryable<T> query,
Func<T, Expression<Func<T, bool>>> predicate)
{
if(predicate==null) throw new ArgumentNullException("predicate");
return query.Where(predicate(default(T)));
}
static Expression<Func<Customer, bool>> SomeFunc(string arg)
{
return c => c.CompanyName.Contains(arg);
}
}
Basically, "out of the box", you can't have LINQ-to-SQL execute queries that have custom functions in them. In fact only some native methods that can be translated to SQL can be used.
The easiest way around this can unfortunately affect performance depending on how much data you're bringing back from the DB.
Basically, you can only use custom functions in WHERE statments if the data has already been loaded into memory, i.e, SQL have already executed.
The quickest fix for your example would look like this:
var query = from x in table.ToList() where SomeFunctionReturnsBool() select;
Notice the ToList(). It executes the SQL and puts the data into memory. You can now do whatever you want in the WHERE statement/method.
I would just break them out like so:
Expression<Func<Table, bool>> someTreeThatReturnsBool = x => true;
var query = from x in table where someTreeThatReturnsBool select x;
You could create functions that pass around expression trees.
Don't use query syntax for this.
var query = table.Where( x => SomeFunction(x) );