I'm using LINQ to SQL in C# in my application. I need to be able to select a column of a row, depending upon a variable. This is easy for the row as it's a simple where clause, but I'm at a loss with only selecting a specific column. Here is my code so far:
var permissions = (from s in dc.Permissions where s.dashboardname == permission select s.[variablehere]).Single();
Is this easy to accomplish?
Is it possible to change your database structure so that your columns becomes rows? (Pivot your table?)
Eg.
Permissions Table
-----------------
Id
Dashboardname
Page1
Page2
Page3
...
and turn it into
Permissions Table
-----------------
Id
Dashboardname
Pagename
Then you could use the where clause to select the row you want?
I'm not sure that I understand your question completely, so this might be a bit off. But could your problem perhaps be solved by using the LINQ Dynamic Query Library?
You can use the DynamicQuery library
against any LINQ data provider
(including LINQ to SQL, LINQ to
Objects, LINQ to XML, LINQ to
Entities, LINQ to SharePoint, LINQ to
TerraServer, etc). Instead of using
language operators or type-safe lambda
extension methods to construct your
LINQ queries, the dynamic query
library provides you with string based
extension methods that you can pass
any string expression into.
See the above link for samples and downloads.
I don't think this is either possible or a good practice. Note that if the variable name is provided by user he or she can easily take all the data they want. Maybe you should try using enumeration and switch() clause?
Say the class that holds the permissions is named Permission, you can define an extension method:
public static class PermissionExtensions
{
public static object SelectProperty(this Permission obj, string variable)
{
return obj.GetType().GetProperty(variable).GetValue(obj, null);
}
}
You can use this in your query like this:
(from s in dc.Permissions where s.dashboardname == permission select s)
.Single().SelectProperty(variable);
This doesn't select the property in the query but instead gets it from the instance.
Another answer that came in my mind is to create table with key-value pairs i.e.
dashboard
key
value
where primary key is (dashboard, key).
Related
Sounds trivial but I cannot find an elegant answer to this: how do I read all rows of a specific column into a list of strings for instance using LINQ on Entity Framework context?
You could try something as simple as the following:
var rows = dbContext.TableName.Select(x=>x.ColumName);
where dbContext is the class you use to "talk" with your database, TableName is the name of the table, whose column values you want to read and ColumnName is the name of the column.
Furthermore, if you place a ToList after the Select, you will create list of objects whose type would be the type of the values in column called ColumnName.
Christos answer will just give you an IQueryable. If you want an actual List you need to do something with the IQueryable:
var rows = dbContext.TableName.Select(x=>x.ColumName).ToList();
though I might go for the LINQ syntax:
var rows = (from c in dbContext.TableName
select c.ColumnName).ToList();
The two forms are equivalent.
i would like to make a linq to sql provider that allow to me to query onto a table that is nor mapped in the datamodel nor known.
I only know a table's alias that i use to query another known table for translation (from the alias to the real table name), after that i will using standard linq to query the real table, read data, and put each results into a dynamic's object.
To achieve that i suppose i need to define a custom linq provider that will manipulate the expression tree, and then call standard linq to sql; but at moment i don't know how do it.
So my aim is that i would write code like this :
List<dynamic> rows = form book in context.Book
where book.Author = "Author"
select book;
Thank in advance for any suggestion.
You can use Reflection:
PropertyInfo table = typeof(ContextType).GetProperty(TableName);
from book in table.GetValue(Context)
...
Say I have a table Table1 with a string field [ProductString] with values:
Alpha, alphanumeric or numeric: eg ABC, B4, U2, C 5, 100, U1, U5, U6, U11
I want to be able to take a where clause like "ProductString >= U5", and pass this to a LINQ statement as a string so it evaluates
Table1.Where(t=> t.ProductString >= 'U5');
Normally this would return results U5 and U6.
However, this I want to be able to use a NaturalSortComparer somehow so that the results returned are U5, U6 and U11.
I know how to use the comparer in an OrderBy, by I wanted to be able to use it at the Where stage.
Using natural sort comparer:
var comparer = new NaturalComparer();
Table1.Where(t=>
comparer.Compare(t.ProductString, "U5") >= 0);
Presuming all your product strings is on the format U%number% then why not abuse that fact?
Table1.Where(t=> int.Parse(t.ProductString.Replace("U","")) >= 5);
If you're using LINQ to Entities I'm not certain this will compile to a store expression (i.e that SQL knows what to do with this - I guess it should).
I'm a little confused, given the accepted answer, about whether this question relates to LINQ to Entities or not. The accepted answer doesn't appear to be a solution that would work in the LINQ to Entities context, but the comments on the question by the OP seem to confirm that this is being executed in the database context. Anyway, this answer is specifically targeted toward LINQ to Entities.
I think doing this in SQL Server would be hard, but not impossible. The problem is that .NET knows what NaturalSortComparer is, but SQL Server (where you want the query to ultimately take place) has no such concept. The best idea I can think of would consist of 2 parts:
Create a UDF (User Defined Function) in SQL server that will give a product that is orderable via natural sort: CREATE FUNCTION Naturalize(#val as nvarchar(max)) RETURNS nvarchar(1000). There's a pretty cool answer here that creates a UDF wrapper around a CLR function to accomplish just that.
Next create a function mapping for your DbContext that maps the UDF above to a function that can be called inside an EF query against the DbContext. Something like this:
[DbFunction("MyContext", "Naturalize")]
public static string Naturalize(this string value)
{
throw new NotSupportedException("This function can only be invoked from LINQ to Entities.");
}
Once you've got these two pieces in place, you can readily use this new function inside an entity query to compare strings using the Naturalized value in the comparison:
Table1.Where(t=> t.ProductString.Naturalize() >= "U5".Naturalize());
Bear in mind that the UDF will be executed against every row contained in the query, which is the whole table in the above example. You'll want to make sure to pare down your query to something manageable before applying the function as a sub-query. Or you may want to try applying some type of UDF-based index on the table in question.
If you are going to be doing searches like this a lot, then what will be the best thing to do is add two new fields to your table, [ProductCode] & [ProductNumber] which separate the two parts of the [ProductString].
Then you comparison becomes:
Table1.Where(t=> t.ProductCode == "U" && t.ProductNumer > 5);
I have some trouble with LINQ. In my program I generate a SQL search query like
select * from emp "where empId=1 and empname='abc'"
(where the quoted text is generated in my code). I can pass the generated "where empId..." string text to the SQL query.
I'd like to do the same thing in LINQ - I want to pass this string as the search criteria i.e. something like
var employee=from a in Employee.AsEnumerable()
"where empId=1 and empname='abc'"
select a;
Is this possible? Thanks in advance.
You can take the base query (in your case Employee.AsEnumerable()) and use the logic you use to generate the string to compose a new query. For example:
if(/*your logic for generating the string "where empId=1" here*/)
{
query = query.Where(a.empId == 1);
}
if(/*your logic for generating the string "empname='abc'" here*/)
{
query = query.Where(a.empname == "abc");
}
The resulting query object will have all the operators composed. However as others have said this is not trivial in the general case. It is not trivial with SQL strings either. If all you need to generate are several filters it will work but if you need complex expressions it will be a problem.
101 LINQ Samples
It's pretty hard, unless you intend to employ:
Dynamic code compilation, or
You are willing to create a (very complicated) parser to analyze the query and call the respective linq extension methods
I personally have no experience in the latter. As for the former, it is a bit tricky and can go nastily wrong if you don't do proper caching and security checks. Executable code injection is very dangerous.
I think you had better use different methods to filter content using methods like Where() if the number of queries can be predetermined or return to SQL if not. Usually you don't need to do this unless the query is manually entered by the user.
I dont't know how to describe the title better (so feel free to change) but essntial I want to produce the equivilent of the following statement in LINQ to SQL:
select * from products where category in ('shoes','boots')
The fields will be coming from the query string essentially (more secure than this but for ease of explanation) i.e
string[] myfields = request.querystring["categories"].split(',');
Thanks
Yes, you use Contains:
db.Products.Where(product => myFields.Contains(product.Category))
aka
from product in db.Products
where myFields.Contains(product.Category)
select product
As other have mentioned, yes it does using the .Contains method. To benefit the other random people that may arrive here via Bing (or any of the other search engines): Linq-To-Entities does not support the .Contains method in the current version. However, with a simple extension method, you can do so:
http://george.tsiokos.com/posts/2007/11/30/linq-where-x-in/
In theory you would use contains:
var productList = from product in context.Products
where myfields.contains(product.category)
select product
However you'll need to test this - I seem to recall there being a bug in the Linq2Sql optimizer when trying to deal with List<> and array values being used like this (it may have only occured if you tried to cast them as IQueryable)