I would like to retrieve a document if one of its collections has an item with a certain Id in it. This is the query I have:
var query = from x in session.Query<MailPackageLog>()
where x.Package != null
where ((x.Package.To != null && x.Package.To.Select(y => y.Id).Contains(recipientId))
|| (x.Package.Cc != null && x.Package.Cc.Select(y => y.Id).Contains(recipientId))
|| (x.Package.Bcc != null && x.Package.Bcc.Select(y => y.Id).Contains(recipientId)))
select x;
query = query.Customize(x => x.WaitForNonStaleResultsAsOfNow(Settings.Default.DocumentStoreQueryTimeout));
return query.FirstOrDefault();
But I am getting this exception when it runs:
System.InvalidOperationException: Cannot understand how to translate
x.Package.To.Select(y => y.Id)
Is this a bug or am I just doing it wrong?
Instead of:
x.Package.To.Select(y => y.Id).Contains(recipientId)
Try this:
x.Package.To.Any(y => y.Id == recipientId)
Semantically they are the same, but Raven may have an easier time translating the second one.
You may also wish to review the "Filtering" section of the RavenDB documentation. This is similar to the "Where + Any" example show there.
Related
In Sitefinity v12.x I would like to create a widget that allows the user to select one or more Categories (Hierarchical Taxons) to use as filter criteria, and after which the widget would query for Pages that have these Categories assigned to them. This seems simple enough on the surface but I can't seem to pull it all together.
I've added "Category" as a Custom Field to the Page data and I've created my test pages. What I'm struggling with is forming the query that can access the custom field "Category" and then compare those against the categories provided by the user.
I've tinkered for awhile but it seems the issue I'm having is retrieving the Categories assigned to a Page from within the Linq query. I've tried var categories = pageNode.GetValue("Category") on it's own and that works as expected. But when I try to use the .GetValue("Category") method in a Linq query this does not seem to be valid, here is an example of what I mean:
var pageManager = PageManager.GetManager();
var pages = pageManager.GetPageDataList().Where(pageData =>
(pageData.Culture == "en" ||
pageData.NavigationNode.LocalizationStrategy != Telerik.Sitefinity.Localization.LocalizationStrategy.Split) &&
pageData.NavigationNode.NodeType == Telerik.Sitefinity.Pages.Model.NodeType.Standard &&
pageData.NavigationNode.RootNodeId == Telerik.Sitefinity.Abstractions.SiteInitializer.CurrentFrontendRootNodeId &&
pageData.Status == ContentLifecycleStatus.Live)
.Select(x => x.NavigationNode);
foreach (PageNode page in pages)
{
// This properly retrieves Categories assigned to a Page in the Debug window
var categories = page.GetValue("Category");
}
// This does not work, error message below .Any() reads: 'object' does not contain a definition for 'Any' and no accessible extension method 'Any' accepting a first argument of type 'object' could be found
var categoryPages = pages
.Where(pageData => pageData.GetValue("Category").Any())
.ToList();
Is there a way I can use/access the Custom Field "Category" on a Page from within a Linq query? Or do I have to go about this some other way?
Thank you in advance for any guidance!
As a note, don't forget to filter the pages for visible and not deleted.
pageData.Status == ContentLifecycleStatus.Live && pageData.IsDeleted == false && pageData.Visible == true)
You should cast pageData.GetValue("Category") to either Guid? or IEnumerable<Guid?> depending how exactly you have set the custom field up.
Thank you for the tips everyone! I was able to sort it out by specifying the type of the Custom Value in the Linq query, like so: pageData.GetValue<TrackedList<Guid>>("Category"), here's what I came up with:
var pageManager = PageManager.GetManager();
var pages = pageManager.GetPageDataList().Where(pageData =>
(pageData.Culture == "en" ||
pageData.NavigationNode.LocalizationStrategy != Telerik.Sitefinity.Localization.LocalizationStrategy.Split) &&
pageData.NavigationNode.NodeType == NodeType.Standard &&
pageData.NavigationNode.RootNodeId == Telerik.Sitefinity.Abstractions.SiteInitializer.CurrentFrontendRootNodeId &&
pageData.Status == ContentLifecycleStatus.Live && pageData.Visible == true)
.Select(x => x.NavigationNode);
var filteredPages = pages
.Where(pageData => categoriesQuery.All(c => pageData.GetValue<TrackedList<Guid>>("Category").Contains(c)))
.ToList();
I am current having an issue with getting records from database using nhibernate.
My 'publicstring' column is having two values, one with lower case and the other with upper case.
I am trying to fetch one of them depending on what is typed.
Below is my query
private string _publicId;
var _mediaFileShare = this.Session.QueryOver<MediaFileShare>()
.Where(q => q.Publicsting == _publicstring)
.SingleOrDefault();
Answers would be appreciated..
A naive solution is:
var _mediaFileShare = this.Session.QueryOver<MediaFileShare>()
.Where(q => q.PublicString == _publicString)
.List()
.SingleOrDefault(r => string.Compare(r.PublicString, _publicString, StringComparison.Ordinal) == 0);
If you're confident that the query will always return two rows then performance should be very acceptable. Alternatively you could use a dynamic order by, something like:
var query = this.Session.QueryOver<MediaFileShare>()
.Where(q => q.PublicString == _publicString);
query = _publicString == _publicString.ToLower()
? query.OrderBy(q => q.PublicString)
: query.OrderByDescending(q => q.PublicString);
var _mediaFileShare = query.Take(1).SingleOrDefault();
The results using an order by will be dependent on your database and its collation setting.
I have a main VendorProfile table and a 1-many VendorHistory table that contains status codes and date stamps. The query below works at retrieving only the latest status (status code and date) for each vendor. However, the view allows the user to select checkboxes of any of the status codes to filter the view. So I need to add a where clause that matches ANY of the checkbox StatusSelections.
Model Diagram
public IEnumerable<BrowseStatusModel> BrowseByStatus(int[] StatusSelections)
{
IQueryable<BrowseStatusModel> query = _db.VendorProfiles
.Include("VendorStatusHistory")
.Include("StatusCodes")
.Select(s => new BrowseStatusModel
{
ProfileID = s.ProfileID,
Name = s.Name,
CompanyName = s.CompanyName,
CompanyDBA = s.CompanyDBA,
DateCreated = s.DateCreated,
Status = s.VendorStatusHistories.OrderByDescending(o => o.DateCreated).FirstOrDefault().Id,
StatusDate = s.VendorStatusHistories.OrderByDescending(o => o.DateCreated).FirstOrDefault().DateCreated
})
.OrderBy(x => x.ProfileID);
foreach (int status in StatusSelections)
{
query = query.Where(x => x.Status == status);
}
return query;
}
The above foreach loop works but, unfortunately creates AND condition where ALL selections must be true instead of ANY. I figured I would have to use a where clause with the following in some way but have been unsuccessful at the correct syntax.
.AsQueryable().Any();
Use contains in the place of that foreach loop
query = query.Where(x => StatusSelections.Contains(x.Status))
how can i achieve this query with Nhibernate Linq?
var l = session.CreateQuery("from Auswahl a where a.Returnkey is not null").List<Auswahl>();
i tried this but it always returns an empty list.
var l = session.Linq<Auswahl>()
.Where(item => !String.IsNullOrEmpty(item.Returnkey))
.Select(item => item)
.ToList();
Have you tried:
var l = session.Linq<Auswahl>()
.Where(item => item.Returnkey != null && item.Returnkey != "")
.Select(item => item)
.ToList();
I'm not sure that using String.IsNullOrEmpty would work, also it checks for two conditions - if it's NULL and if it's a blank empty string, how would that get translated into SQL? Might be worth having a look at SQL Profiler to see the raw SQL query it generates.
I would like to make this query:
Session.Linq<User>().Where(u => u.Payments.Count(p => p.Date != null) > 0);
In plain English I want to get all the users that has at least one payment with the date specified.
When I run the sample code I get a System.ArgumentException with the message:
System.ArgumentException : Could not find a matching criteria info provider to: this.Id = sub.Id
Do you know a solution to this problem?
It would also be very helpful if someone could provide the same query with the NHibernate Query by Criteria API.
I'm not sure if this will work in your particular case, but I would use the .Any() extension to clean up the linq query a bit; for example:
Session.Linq<User>().Where(u => u.Payments.Any(p => p.Date != null));
I think something like it:
Customer customerAlias = null;
criteria = CurrentSession.CreateCriteria(typeof(User), () => customerAlias);
if (searchCriteria.OrdersNumber.HasValue)
{
ICriteria paymentsCriteria = criteria.CreateCriteria<Customer>(x => x.Payments);
DetachedCriteria paymentsCount = DetachedCriteria.For<Payment>();
paymentsCount.SetProjection(Projections.RowCount());
paymentsCount.Add(SqlExpression.NotNull<Payment>(x => x.Date));
paymentsCount.Add<Payment>(x => x.Customer.Id == customerAlias.Id);
paymentsCriteria.Add(Subqueries.Gt(1, paymentsCount));
}
return criteria.List<User>();