I have a List and i want to write a query about List's ids Contains specific table id.
i Write this and running true but i want to write all in same query..
List<int> tempList=yetkiUygulamaList.Select(y => y.Id).ToList();
query = query.Where(x => tempList.Contains(x.Uygulama.Id));
Wrong Query
query = query.Where(x => yetkiUygulamaList.Select(y =>y.Id).ToList().Contains(x.Uygulama.Id));
this must works
query = query.Where(x => yetkiUygulamaList.Any(y=>y.Id == x.Uygulama.Id));
you can perform a join, it would be more simple and suitable in your case.
If I understand, query is a "collection" of a class (let's call it AObj) containing a property Uygulama and the class Uygulama contains a property Id and yetkiUygulamaList is a "collection" of Uygulama
//will return a IEnumerable<AObj>
IEnumerable<AObj> query = query.Join(yetkiUygulamaList, a => a.Uygulama.Id, u => u.Id, (a,u)=>a);
ToList() materilizes by executing the query, and after that there is no way for NHibernate to understand that the first query should be included as a subquery.
Just remove the useless ToList():
IQueryable<int> tempList = yetkiUygulamaList.Select(y => y.Id); // removed here
query = query.Where(x => tempList.Contains(x.Uygulama.Id));
The above code will generate a single SQL query. If you want to stick it all in one C# code line, just get rid of the intermediary variable:
query = query.Where(x => yetkiUygulamaList.Select(y => y.Id).Contains(x.Uygulama.Id));
Related
I am trying to query my Database for a single record ins three steps and I am having problems getting the result that I am looking for. These are the steps that I created:
client = client
.Where(s => s.CompanyName.Contains(name));
var res = client.Select(x => x.ID);
Tracker = Tracker
.Where(s => s.ClientId.Equals(client.Select(x => x.ID)));
Debugging the code indicated that steps one and two worked correctly and generated the data that I needed to run my third query, which should provide the whole record, utilizing the result of the second step.
The third and last steps generated the following error:
"The LINQ expression DbSet<TimeTrackerViewModel>().Where(t => t.ClientId.Equals(DbSet<ClientsViewModel>().Where(c => c.CompanyName.Contains(__name_0)).Select(c => c.ID))) could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information."
How do I query my database, utilizing the query result from the second step?
If you want to use the IDs in res to filter Tracker then you can use Any():
var res = client.Select(x => x.ID);
trackers = Tracker.Where(s => res.Any(r => r == s.ClientId));
The above query will return a collection.
I am trying to query my Database for a single record
If you want to return a single record then you could to use FirstOrDefault(), either in place of the Where clause (using the same predicate), or after the Where (you could consider Single() if you know there's exactly 1 matching record). But you should also consider what you expect to happen if multiple records match the name parameter in your first query and how you would handle that.
You should try this:
var trakers = (from c in client.Where(s => s.CompanyName.Contains(name))
join t in tracker
on c.ID
equals t.ClientId
select t).ToList();
So you do only a query on db.
After reading several related posts, I was able to combine thier ideas into a single working solution as posted below:
var client = _context.ClientsViewModel
.Where(s => s.CompanyName.Contains(name))
.Select(x => x.ID).ToList();
Tracker = Tracker
.Where(s => s.ClientId == client[0])
.OrderByDescending(x => x.Id);
I want to search using soundex() with each words of a sentence.
My C# code is:
all_data = db.SearchEntities.Where(
s => (s.EventTitlePrimaryLang
.Split(' ')
.ToArray()
.Any(d => SqlFunctions.SoundCode(d.ToString()) ==
SqlFunctions.SoundCode(srQuery.ToString())
))
)
//.AsEnumerable()
//.AsQueryable()
.ToList();
Getting this error
LINQ to Entities does not recognize the method 'System.String[]
ToArrayString'
method, and this method cannot be translated into a store expression.
Your issue is that you are attempting to filter on the split results of a property in your query. Everything in the .Where() clause off the DbSet called SearchEntities will need to be evaluated as SQL.
The error message is telling you that EF can't convert x.MyProperty.Split() into SQL.
The only alternative, which might not be desirable in this case is to have a more general filter, then perform the complex filtering in you materialised results.
db.SearchEntities.Where(s => Something general to narrow down your results)
.AsEnumerable() // materialise your results
.Where(s => s.EventTitlePrimaryLang
.Split(' ')
.Any(d => something specific with your d and sQuery))
.ToArray();
all_data = db.SearchEntities.Where(x => !string.IsNullOrWhiteSpace(x.EventTitlePrimaryLang))
.ToList();
var filteredData = all_data.Where(s => (s.EventTitlePrimaryLang.Split(' ')
.Any(d => SqlFunctions.SoundCode(d)) == SqlFunctions.SoundCode(srQuery)))
.ToList();
OR
all_data = db.SearchEntities.Where(x => !string.IsNullOrWhiteSpace(x.EventTitlePrimaryLang))
.AsEnumerable()
.Where(s => (s.EventTitlePrimaryLang.Split(' ')
.Any(d => SqlFunctions.SoundCode(d)) == SqlFunctions.SoundCode(srQuery)))
.ToList();
As Pointed out by reckface in another answer.
OR
As another alternative to the above which may or may not work, you could opt to build the query using for loops.
var results = db.SearchEntities.Where(x => !string.IsNullOrWhiteSpace(x.EventTitlePrimaryLang))
.AsQueryable();
foreach(var r in results) {
var langSplit = s.EventTitlePrimaryLang.Split(' ');
foreach(var val in langSplit) {
results = from a in results
where SqlFunctions.SoundCode(val) == SqlFunctions.SoundCode(srQuery)
select a;
}
}
return results.ToList();
The above would then filter your results bit by bit.
EDIT:
Removed The redundant .ToString() calls
EDIT 2:
Edited the code example to better help fix the problem and Identify what is wrong.
The problem is that Entity Framework cannot convert .Split(' ') into valid SQL Code. As a work around, you will need to retrieve the data first, then filter that data using LINQ
EDIT 3:
Added possibly another way to solve the issue by using .AsQueryable() to filter down the results. Thus you don't need to query the database for a large dataset and filter the results, you could get the filtered results from the db directly, assuming it dosen't build the split into the database query. I have not tested it.
I'm trying to find all customer codes where the customer has a status of "A" and whose code does not contain any letter using LINQ query.
var activeCustomers = Customers.Where(x => x.Status == "A" && x.Code.Any(n => !char.IsLetter(n))).Select(x => x.Code);
When I run this query in LinqPad I get the following error:
You'll need to do this as a two part query. First, you could get all the users who's status is "A":
var activeCustomers = Customers.Where(x => x.Status == "A").ToList();
After you've got those in-memory, you can create an additional filter for char.IsDigit:
var codes = activeCustomers.Where(x => x.Code.Any(n => !char.IsLetter(n)))
.Select(x => x.Code)
.ToArray();
As commenters have stated, IsLetter() cannot be translated to SQL. However, you could do the following, which will first retrieve all items with Status "A" from the database, then will apply your criteria after retrieval:
var activeCustomers = Customers.Where(x => x.Status == "A").AsEnumerable().Where(x => x.Code.Any(n => !char.IsLetter(n))).Select(x => x.Code);
You'll have to determine if it's acceptable (from a performance perspective) to retrieve all customers with "A" and then process.
The AsEnumerable() transitions your LINQ query to working not with IQueryable (which works with SQL) but with IEnumerable, which is used for plain LINQ to objects.
Since it is LINQ 2 SQL, there is no natural way to translate char.IsLetter to something SQL can understand. You can hydrate a query that retrieves your potential candidates and then apply an addition in-memory filter. This also solves the issue where LINQ 2 SQL has a preference for a string and you are dealing with chars
var activeCustomers = Customers.Where(x => x.Status == "A").ToList();
var filteredCustomers = activeCustomers.Where(x =>
x.Code.Any(n => !char.IsLetter(n))).Select(x => x.Code).ToList();
There are two performance hits here. First, you're retrieving all potential records, which isn't too desirable. Second, in your above code you were only interested in an enumerable collection of codes, which means our query is including far more data than we originally wanted.
You could tighten up the query by only returning back to columns necessary to apply your filtering:
var activeCustomers = Customers.Where(x => x.Status == "A")
Select(x => new Customer{ Status = x.Status, Code = x.Code }).ToList();
You still return more sets than you need, but your query includes fewer columns.
I am doing this in LINQ TO SQL:
var query = Database.ExtendedUsers.Select(x => x).Where(x => x.Acolumn >= 4);
which generates the correct SQL syntax (with where clause).
If I add a 2nd where, it is ignored:
var query = Database.ExtendedUsers.Select(x => x).Where(x => x.Acolumn >= 4);
query.Where(x => x.AnotherColumn.Equals(2));
The second where clause isn't added to the SQL query.
What am I doing wrong?
Basically, I want to dynamically add where's
query.Where(...);
query.Where(...);
query.Where(...);
query.ToList(); /: result
The problem is that Where returns new IQueryable implementation (with added proper nodes in Expression Tree that is used to generate SQL). So basically, you just need to assign result back to the query variable:
query = query.Where(x => x.AnotherColumn.Equals(2));
Editor: please do not change my post and add code I didn't have posted (add comment instead). The OP wants to use where dynamically (f.e. based on conditions). Sample:
var query = Context.MyTable.Where(tbl => tbl.Col > 4);
if (someConditionThatCannotBeEvalutedInLinqToSql)
{
query = query.Where(2)tabl => table.Col2 == 5);
}
So, Where(x => x.Acolumn >= 4 && x.AnotherColumn.Equals(2)) is not always solution and I don't believe that is what the OP needs.
In orchard cms i want to write a query containing two condition over two different ContentPartRecord combined with OR clause. one possible way to combine conditions is :
var query = _contentManager.HqlQuery()
.Where(a => a.ContentPartRecord<ProductPartRecord>(), a => a.Eq("Title", "myTitle"))
.Where(a => a.ContentPartRecord<TitlePartRecord>(), a => a.Eq("Price", 1000))
.List();
but this one combines two condition with And clause. i think something like following along with some changes (which would be the answer for this question) could be the case:
var query = _contentManager.HqlQuery()
.Join(a => a.ContentPartRecord<ProductPartRecord>())
.Join(a => a.ContentPartRecord<TitlePartRecord>())
.Where(a => a.ContentItem(),
a => a.Or(p => p.Eq("ProductPartRecord.Price",
"1000"), t => t.Eq("TitlePartRecord.Title", "myTitle")))
.List();
but i couldn't get it working.any body have any suggestion?
When you use where clause in HqlQuery you need to pass Alias (as first parameter). Alias means that you will be apply where clause to specific table (class that represent this table). And when you use OR clause that you definitely need to compare columns of the specific table in two parts of OR clause (left and right from the OR clause). And i think this is not possible to do you need a standard way.
But you can use:
Action<IAliasFactory> productPartRecordAlias = x => x.ContentPartRecord<ProductPartRecord>().Named("productPartRecord");
Action<IAliasFactory> titlePartRecordAlias = x => x.ContentPartRecord<TitlePartRecord>().Named("titlePartRecord");
var query = _contentManager.HqlQuery()
.Join(productPartRecordAlias)
.Join(titlePartRecordAlias)
.Where(a => a.ContentItem(), p => p.Gt("Id", "0 AND (productPartRecord.Price = 1000 OR titlePartRecord.Title = 'myTitle')"));