Replacing foreach on a list with LINQ - linq

I'm not sure if this would be desirable, but is there a LINQ "way" of replacing the following:
foreach (var u in users)
context.Users.Add(u);
with something like
context.Users.Add(....);

Assuming users is type List<User> you just do
users.ForEach(u => context.Users.Add(u));
though you don't need to use LINQ. You could just do
context.Users.AddRange(users);

You don't need LINQ. You need to use AddRange instead of Add:
context.Users.AddRange(users);
Assumption: you're using Entity Framework and Users is of type DbSet<T>

If Users is a DbSet then you can probably do without looping at all by using AddRange:
context.Users.AddRange(users);
However if you really want to use Linq, then you can also do this:
users.ToList().ForEach(u => context.Users.Add(u));
Or the shorthand version:
users.ToList().ForEach(context.Users.Add);

Related

Quarkus PanacheEntityBase query with IN

I have a customer entity of type PanacheEntityBase. I would like get all customers by ids
I can get it with customer.list("customerId", id) in a loop. I dont think its a good solution. I prefer using IN. Please suggest how to use IN with PanacheEntityBase
I solved the problem with customerEntity.list("customerId IN (?1)", customerIds);
Note: customersids must be a java list (Array did not work)

DBSet and dynamic sql expressions

So I have Products class that represent the products table.
To get all the records I do:
db.Products.ToList()
And I have a string like this:
String queryString = "mp=5 AND optic=TRUE AND price=500";
My question is how can I use this string to filter Products? Where func only accept lambda expressions..
Thanks
I'm not sure if it's still supported or not, but you can use Dynamic LINQ to allow you to add 'text' based expressions as you require. See:
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
http://pranayamr.blogspot.com/2011/04/dynamic-query-with-linq.html
You may also want to think about using a Predicate builder to do the same job more declaratively. There are a few out there, but one that I've used with great success is the albahari one:
http://www.albahari.com/nutshell/predicatebuilder.aspx
hope this helps..
You can execute Raw SQL against the DbSet and return a strong typed list. For detail, please refer to this blog post by EF team.

OrderBy("it." + sort) -- Hard coding in LINQ to Entity framework?

I have been trying to use dynamic LINQ to Entity in my application for specifying the OrderBy attribute at runtime. However when using the code as described in the majority of documentation:
var query = context.Customer.OrderBy("Name");
I received the following exception:
System.Data.EntitySqlException: 'Name' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly.
After much searching I found this MSDN page:
http://msdn.microsoft.com/en-us/library/bb358828.aspx
Which included the following code example:
ObjectQuery<Product> productQuery2 = productQuery1.OrderBy("it.ProductID");
This prompted me to change my code to the following:
var query = context.Customer.OrderBy("it.Name");
After this the code works perfectly. Would anyone be able to confirm that this is indeed the correct way to get OrderBy working with LINQ to Entity? I can’t believe that the framework would have been implemented in this way, perhaps I have overlooked something?
Thanks, Matt
The it.Name syntax is ESQL and is indeed specific to the EF. There are good reasons to use this sometimes (e.g., collation specifiers), but it's not what I normally do.
Usually I use standard LINQ expressions:
var query = context.Customer.OrderBy(p => p.Name);
You can also use System.Linq.Dynamic, if you download it from Code Gallery, and then your original query:
var query = context.Customer.OrderBy("Name");
...will work.
No nice way, so far
My answer to this question was to create a stored procedure which has parameter to control sorting.

Updating tables with Linq expressions

Most of the examples I've found deal with Linq to entities, which is not what I need. I have a standard DataTable which I need to modify before returning to the caller. I can iterate over the normal Table.Rows collection or do something like this with the new extension methods:
foreach (var x in table.AsEnumerable()) {
if (x.Field<int>("SomeField") > SomeValue)
x.SetField<string>("OtherField", "OtherValue");
}
But I'm still manually looping through the entire row collection. Not necessarily a big deal, but I'm wondering if there's a more elegant way to accomplish this with Linq somehow, in the sense that I need to create an expression that iterates over the results of a query and performs an arbitrary action, rather than just select elements from the container being enumerated.
I think what you're wondering is if there's some sort of extension method like
stuff.ForEach(x => x.Value = "new value");
Unfortunately, there is no such thing. When I began using LINQ to SQL, I wanted the same thing. But unfortunately, you must use a for loop.

LINQ multiple where clause

I have a course table which I need to search based on keywords typed in the search box.
Here is a sample query:
SELECT * FROM Courses WHERE
Title LIKE '%word%' OR Title LIKE '%excel%' OR
Contents LIKE '%word%' OR Contents LIKE '%excel%'
How can I convert this in LINQ where LINQ would dynamically generate WHERE statements based on each keywords.
I tried to user PredicateBuilder it works fine as long as the field is VARCHAR. For the "TEXT" fields the quotes are not generated thus causing compiler to give an error message. Here is the SQL generated by PredicateBuilder
SELECT [t0].[CoursesID], [t0].[Title], [t0].[Contents], [t0].[Active],
FROM [dbo].[Courses] AS [t0]
WHERE ([t0].[Title] LIKE '%word%') OR ([t0].[Contents] LIKE %word%) OR
([t0].Title] LIKE '%excel%') OR ([t0].[Contents] LIKE %excel%)
Notice there is no single Quote for the "Contents" field which is a Text field in the database.
Is there any easy way to build WHERE statement and attach it with query? Does anyone know how I can do this without PredicateBuilder?
Thanks in advance.
Since you are working w/ LINQ I suppose you are working against a LINQ-to-SQL data context right? I don't have a spare DataContext lying around to test this, but this should give you some ideas.
I don't know if it will work against data context though, but most of these are pretty basic stuff (chaining OR operator and Contains method call) so it shouldn't cause problem when the query translates to SQL.
First I create a custom function that would build my predicate:
Func<string, Func<DataItem, bool>> buildKeywordPredicate =
keyword =>
x => x.Title.Contains(keyword)
|| x.Contents.Contains(keyword);
This is a function which takes a single string keyword and then return another function which takes a DataItem and checks it against the keyword.
Basically, if you pass in "Stack", you'll get a predicate: x => x.Title.Contains("Stack") || x.Contents.Contains("Stack").
Next, since there are many possible keywords and you need to chain it with an OR operation, I create another helper function to chain 2 predicates together with an OR
Func<Func<DataItem,bool>, Func<DataItem, bool>, Func<DataItem, bool>> buildOrPredicate =
(pred1, pred2) =>
x => pred1(x) || pred2(x);
This function takes 2 predicates and then join them up with an OR operation.
Having those 2 functions, I can then build my where predicate like this:
foreach (var word in keywords) {
filter = filter == null
? buildKeywordPredicate(word)
: buildOrPredicate(filter, buildKeywordPredicate(word));
}
The first line inside the loop basically checks if the filter is null. If it is, then we want a simple keyword filter built for us.
Else if the filter is not null, we need to chain existing filters with an OR operation, so we pass the existing filter and a new keyword filter to buildOrPredicate to do just that.
And then we can now create the WHERE part of the query:
var result = data.Where(filter);
Passing in the complicated predicate we've just built.
I don't know if this will different from using PredicateBuilder but since we are deferring query translation to the LINQ-to-SQL engine, there should not be any problems.
But as I said, I havn't tested it against a real data context, so if there's any problems you can write in the comments.
Here's the console app that I built to test: http://pastebin.com/feb8cc1e
Hope this helps!
EDIT: For a more generic and reusable version which involves properly utilizing the Expression Trees in LINQ, check out Thomas Petricek's blog post: http://tomasp.net/articles/dynamic-linq-queries.aspx
As predicate builder doesn't know the DB type of the property the Contains method is called on, I guess this might be a problem inside linq to sql. Have you tried with a normal query (not with predicate builder) and a TEXT column with Contains?

Resources