NHibernate QueryOver where ID is in a list - asp.net-mvc

I have a webpage with criteria fields which filters data. The query for this is:
CompanyAddress ca = null;
CompanyAddress cad = null;
WorkInfo wi = null;
PrivateInfo pi = null;
SearchResultInfo sri = null;
/***************************/
/* SEARCH FOR MAIN COMPANY */
/***************************/
var company = Session.QueryOver<Company>()
.JoinAlias(c => c.Addresses, () => ca)
.Where(() => ca.Main)
.Where(c => c.Status == ContactStatus.Approved)
.Select(
Projections.Property("Id").WithAlias(() => sri.TopId),
Projections.Property("ca.Id").WithAlias(() => sri.Id),
Projections.Property("Name").WithAlias(() => sri.Name),
Projections.Property("ca.Address").WithAlias(() => sri.Address),
Projections.Property("ca.ContactData").WithAlias(() => sri.ContactData),
Projections.Constant(ContactClassType.Company).WithAlias(() => sri.Type)
);
if (!string.IsNullOrEmpty(_name)) company = company.WhereRestrictionOn(c => c.Name).IsLike("%" + _name + "%");
//// TODO: fix error
if (_selectedTag != null) company = company.Where(Restrictions.In("_selectedTag", ca.Tags.Select(x => x.Tag.Id).ToArray()));
if (!string.IsNullOrEmpty(_selectedCity)) company = company.Where(() => ca.Address.City == _selectedCity);
if (_selectedCountry != null) company = company.Where(() => ca.Address.Country.Id == _selectedCountry);
if (!string.IsNullOrEmpty(_selectedZipCode)) company = company.Where(() => ca.Address.ZipCode == _selectedZipCode);
company.TransformUsing(Transformers.AliasToBean<SearchResultInfo>());
Now if selectedTag has an ID the query gives me an error telling ca is null. All the other where clauses work except this one. So I want to check if the incoming ID is in the Tag list from the object CompanyAddress.
Does anyone have an idea whats wrong here?
** SQL FROM ANDREW WITHTAKERS SOLUTION **
SELECT this_.Id as y0_,
ca1_.Id as y1_,
this_.Name as y2_,
ca1_.IdAddressType as y3_,
ca1_.Street as y4_,
ca1_.Number as y5_,
ca1_.ZipCode as y6_,
ca1_.City as y7_,
ca1_.Country as y8_,
ca1_.Email as y9_,
ca1_.Fax as y10_,
ca1_.PhoneNumber as y11_,
ca1_.CellNumber as y12_,
ca1_.Url as y13_,
#p0 as y14_
FROM CON_Company this_ inner join CON_CompanyAddress ca1_ on this_.Id=ca1_.IdCompany
inner join CON_CompanyAddrTag tagalias2_ on ca1_.Id=tagalias2_.IdCompanyAddr
WHERE ca1_.Main = #p1 and this_.Status = #p2 and tagalias2_.Id = #p3',N'#p0 int,#p1 bit,#p2 int,#p3 int',#p0=3,#p1=1,#p2=0,#p3=3

You're going to have to join to Tag in order to do this:
if (_selectedTag != null)
{
Tag tagAlias = null;
company
.JoinAlias(() => ca.Tags, () => tagAlias)
.Where(() => tagAlias.Id == _selectedTag.Id)
}
(Assuming you want Tags compared by Id)
The thing to remember about QueryOver/Criteria is that it's ultimately going to be turned into SQL. calling ca.Tags.Select(...) doesn't make sense from inside of a SQL query since there's an implied JOIN there to Tag.
Also, you're mixing QueryOver and Criteria syntax which is kind of confusing. I'd rework things a bit:
Company companyAlias = null;
var company = Session.QueryOver<Company>(() => companyAlias)
.JoinAlias(c => c.Addresses, () => ca)
.Where(() => ca.Main)
.Where(c => c.Status == ContactStatus.Approved)
.Select(
Projections.Property(() => companyAlias.Id).WithAlias(() => sri.TopId),
Projections.Property(() => ca.Id).WithAlias(() => sri.Id),
Projections.Property(() => companyAlias.Name).WithAlias(() => sri.Name),
Projections.Property(() => ca.Address).WithAlias(() => sri.Address),
Projections.Property(() => ca.ContactData).WithAlias(() => sri.ContactData),
Projections.Constant(ContactClassType.Company).WithAlias(() => sri.Type)
);

Related

Linq GroupBy Query Timeout

My query with group by always gives timeout error. How can i make it work properly?
var result = products.Join(_Context.Barcode, firstTable => firstTable.ProductId, barcode => barcode.B_ProductId, (resultTable, resultProduct) => new
{
product = resultTable,
barcode = resultProduct
}).Join(_Context.Stock, secondTable => secondTable.barcode.Barcode, stock => stock.Barcode, (finalResult, finalStock) => new
{
Product = finalResult.product,
Stock = finalStock,
Barcode = finalResult.barcode
}).GroupBy(x => x.Product.ProductId).Select(I => new ProductDTO()
{
InStock = I.Sum(x => x.Stock.StockCount) > 0 ? true : false,
Url = I.Select(x => x.Product.Url).FirstOrDefault(),
Name= I.Select(x => x.Product.Name).FirstOrDefault(),
ImagePath = I.Select(x => x.Product.ImagePath).FirstOrDefault(),
Tax = I.Select(x => x.Product.Tax).FirstOrDefault(),
Price = I.Select(x => x.Product.Price).FirstOrDefault(),
Id = I.Select(x => x.Product.ProductId).FirstOrDefault(),
});
return result.ToList();
Thank you.
_Context.Database.CommandTimeout = 600;
use time out function before the result.

nested Linq Query Returned an error at run time(Unable to create a constant value of type Anonymous type)

here you can find the whole Exception https://pastebin.com/gfHdTUKd
var rangeReports = dbCon.RangeReports.Where(x => x.PatientRegistrationId == pidReg)
.Select(x => new { x.TestID, x.Value, x.TestDate })
.OrderBy(x => x.TestDate).Distinct().ToList();
var ReportsData = dbCon.Tests
.Select(t => new
{
ID = t.ID,
Name = t.Name,
reports = rangeReports.Where(rr => rr.TestID == t.ID)
.Select(rr => new { TestDate = rr.TestDate, Value = rr.Value }).ToList()
}).ToList();
If i remove below Line of Code from an above query It works fine, couldn't find exact issue.
reports = rangeReports.Where(rr => rr.TestID == t.ID)
.Select(rr => new { TestDate = rr.TestDate, Value = rr.Value }).ToList()
your help will be highly appreciated
Thank you
If materialize second query first, this should fix the issue:
var ReportsData = dbCon.Tests
.Select(t => new
{
ID = t.ID,
Name = t.Name
})
.ToList() //Materialize the query first
.Select(t => new
{
ID = t.ID,
Name = t.Name,
reports = rangeReports.Where(rr => rr.TestID == t.ID)
.Select(rr => new { TestDate = rr.TestDate, Value = rr.Value }).ToList()
}).ToList();

How to exclude record in elastic Search in ASP.Net MVC

I have to use the elastic search for the show the document.
I have written a query like below.
var result = elastic.Search<DocPosts>(s => s.Index(indexname).AllTypes().From(data.from).Size(data.PageSize).Query(q => q.Bool(b => b.Should(sh =>
sh.Match(mt1 => mt1.OnField(f => f.Text).Query(SQuery)) ||
sh.Match(mt2 => mt2.OnField(f => f.Title).Query(SQuery))
))).Highlight(h => h
.OnFields(f => f.OnField(d => d.DocText).PreTags("<mark>").PostTags("</mark>"), f => f.OnField(d => d.Title).PreTags("<mark>").PostTags("</mark>"))
).Filter(f => f.Term(t => t.Id, Id)));
this is working perfectly.
in this, I want to exclude some record that has come in below query.
var Proc = (from p in db.Pro where p.ParId == ParId && (u.UserId != temp.UserId || u.UserId == null)
select p.procID).ToList();
how can I perform this filter or exclude from elastic search?

Adwords API CampaignCriterionService IpBlock empty IpAddress issue

We've experienced issue with CampaignCriterionService while getting IpAddress value for IpBlock criterion.
https://developers.google.com/adwords/api/docs/reference/v201502/CampaignCriterionService.IpBlock
It is impossible to get IpAddress value. If you use it in selector - you get error [SelectorError.INVALID_FIELD_NAME # serviceSelector; trigger:'IpAddress'].
$selector = new Selector();
$selector->fields = array('Id', 'CriteriaType', 'IpAddress');
$selector->predicates[] = new Predicate('CampaignId', 'EQUALS', $campaign->google_id);
$selector->predicates[] = new Predicate('CriteriaType', 'EQUALS', 'IP_BLOCK');
$selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE);
$page = $campaignCriterionService->get($selector);
After hours of struggle we found that you should use "KeywordText" instead of "IpAddress" to get proper value. This is not obvious at all. Hope this hint saves somebody time and efforts. Such things should be definitely in documentation. So, working code looks like following:
$selector = new Selector();
$selector->fields = array('Id', 'CriteriaType', 'KeywordText');
$selector->predicates[] = new Predicate('CampaignId', 'EQUALS', $campaign->google_id);
$selector->predicates[] = new Predicate('CriteriaType', 'EQUALS', 'IP_BLOCK');
$selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE);
$page = $campaignCriterionService->get($selector);
If you want to use IpAddress as predicate to search by it you should use the same "KeywordText", there is an example:
$selector = new Selector();
$selector->fields = array('Id', 'CriteriaType', 'KeywordText');
$selector->predicates[] = new Predicate('CampaignId', 'EQUALS', $campaign->google_id);
$selector->predicates[] = new Predicate('CriteriaType', 'EQUALS', 'IP_BLOCK');
$selector->predicates[] = new Predicate('KeywordText', 'EQUALS', '192.168.0.1/32');
$selector->paging = new Paging(0, AdWordsConstants::RECOMMENDED_PAGE_SIZE);
$page = $campaignCriterionService->get($selector);
print_r($page);
Produces output:
CampaignCriterionPage Object
(
[entries] => Array
(
[0] => NegativeCampaignCriterion Object
(
[campaignId] => 167195728
[isNegative] => 1
[criterion] => IpBlock Object
(
[ipAddress] => 192.168.0.1/32
[id] => 23078300211
[type] => IP_BLOCK
[CriterionType] => IpBlock
[_parameterMap:Criterion:private] => Array
(
[Criterion.Type] => CriterionType
)
)
[bidModifier] =>
[forwardCompatibilityMap] =>
[CampaignCriterionType] => NegativeCampaignCriterion
[_parameterMap:CampaignCriterion:private] => Array
(
[CampaignCriterion.Type] => CampaignCriterionType
)
)
)
[totalNumEntries] => 1
[PageType] => CampaignCriterionPage
[_parameterMap:Page:private] => Array
(
[Page.Type] => PageType
)
)

NHibernate QueryOver with WhereRestriction as OR

I have this query but I can't seem to find how I set my WhereRestrictionOn as an OR. Now they function as AND but I want one OR the other.
var privateInfo = Session.QueryOver<ConContact>()
.JoinAlias(c => c.PrivateInfos, () => pi)
.WhereRestrictionOn(c => c.FirstName).IsLike(_selectedFirstLetter + "%")
.WhereRestrictionOn(c => c.LastName).IsLike(_selectedFirstLetter + "%") // todo: change to firstname OR lastname
.Where(c => c.Status == ContactStatus.Approved)
.Select(
Projections.Property("pi.Id").WithAlias(() => sri.Id),
Projections.Property("FirstName").WithAlias(() => sri.Name), //todo: get fullname here => Add concontact object in privateinfo
Projections.Property("pi.Address").WithAlias(() => sri.Address),
Projections.Constant("Contact").WithAlias(() => sri.Type)
)
.TransformUsing(Transformers.AliasToBean<SearchResultInfo>())
.List<SearchResultInfo>()
.ToList();
Any help is much appreciated thx!
SOLUTION:
var privateInfo = Session.QueryOver<ConContact>()
.JoinAlias(c => c.PrivateInfos, () => pi)
.Where(
Restrictions.Disjunction()
.Add(Restrictions.Like("FirstName", _selectedFirstLetter + "%"))
.Add(Restrictions.Like("LastName", _selectedFirstLetter + "%"))
)
.Where(c => c.Status == ContactStatus.Approved)
.Select(
Projections.Property("pi.Id").WithAlias(() => sri.Id),
Projections.Property("FirstName").WithAlias(() => sri.Name), //todo: get fullname here => Add concontact object in privateinfo
Projections.Property("pi.Address").WithAlias(() => sri.Address),
Projections.Constant(NewObjectType.Contact).WithAlias(() => sri.Type)
)
.TransformUsing(Transformers.AliasToBean<SearchResultInfo>())
.List<SearchResultInfo>()
.ToList();
The top level .Where() family (including WhereRestrictionOn) is always joined with AND. So we have to explicitly use something like:
Restrictions.Or(restriction1, restriction1)
Restrictions.Disjunction().Add(restriction1).Add(restriction2).Add(...
So, this could be our case:
.Where(
Restrictions.Disjunction()
.Add(Restrictions.On<ConContact>(c => c.FirstName)
.IsLike(_selectedFirstLetter, MatchMode.Start))
.Add(Restrictions.On<ConContact>(c => c.LastName)
.IsLike(_selectedFirstLetter, MatchMode.Start))
// more OR ...
//.Add(Restrictions.On<ConContact>(c => c.MiddleName)
// .IsLike(_selectedFirstLetter, MatchMode.Start))
)
As discussed here: 16.2. Simple Expressions, for simple stuff we can even use || (cited small example):
.Where(p => p.Name == "test name" && (p.Age > 21 || p.HasCar))

Resources