How to do more than one level projection in query over? - nhibernate

I tired this
respondentSanctionSubquery = respondentSanctionSubquery.Select(x => x.Respondent.Incident.Id);
but i got this exception :
i have 3 entities not 2 entities :
class Respondent
{
public IncidentObj{get;set;}
}
class Incident
{
public int Id{get;set;}
}
class RespondentSanction
{
public Respondent RespondentObj{get;set;}
}

You have to join other entities also to the main query (as follows),
X x = null;
Respondent respondent = null;
Incident incident = null;
respondentSanctionSubquery = respondentSanctionSubquery
.JoinQueryOver(() => x.Respondent , () => respondent)
.JoinQueryOver(() => respondent.Incident , () => incident )
.Select(r => incident.Id);
or else you might want to go for subqueries,
X x = null;
Respondent respondent = null;
Incident incident = null;
var subQuery = (QueryOver<Respondent>)session.QueryOver<Respondent>(() => respondent)
.JoinQueryOver(() => respondent.Incident , () => incident )
.Where(() => respondent.Id == x.Respondent.Id)
.Select(r => incident.Id);
var query = session.QueryOver(() => x)
.SelectList(l => l.SelectSubQuery(subQuery));

You have to do a JOIN in order to do a projection like that:
respondentSanctionSubquery =
respondentSanctionSubquery
.JoinQueryOver(x => x.RespondentObj)
.JoinQueryOver(resp => resp.IncidentObj)
.Select(inc => inc.Id);

you should do join between the entities using Join alias
respondentSanctionSubquery =
respondentSanctionSubquery
.JoinAlias(x => x.RespondentObj)
.JoinAlias(resp => resp.IncidentObj)
.Select(inc => inc.Id);
for more information please check this URL :What is the difference between JoinQueryOver and JoinAlias?

Related

how to write a linq with multiple join

as am a beginner,i want to get the following set of query as linq with a detailed explanation
//my sql
select COL.title as organizationtitle,CL.[title] as
cousestitle,sum(FD.feathers) as totalfeathers,sum(FD.amount) as
totalamount
from [dbo].[FeathersDonated] FD
join [dbo].[Couses] C on FD.corpid=3 and FD.[cousesid]=C.id
join [dbo].[Couses_lang] CL on FD.[cousesid]=CL.cousesid and
CL.language='en-US'
JOIN [dbo].[Organization_lang] COL on COL.orgid=2 and COL.language='en
US'
group by FD.cousesid,CL.[title],CL.[description],COL.title
i have tried the following set of code. please do help
var featherDonated = _GoUoW.FeathersDonated.FindBy(x => x.corpid ==
param.corpid)
.GroupBy(x => x.cousesid).Select(x => new { cousesid = x.Key, amount =
x.Select(a => a.amount).DefaultIfEmpty(0).Sum(), feathers = x.Select(a =>
a.feathers).DefaultIfEmpty(0).Sum() })
.Join(_GoUoW.Couses.GetAll(), feather => feather.cousesid, couse =>
couse.id, (feather, couse) => new { feather, couse })
.Join(_GoUoW.Organization_lang.FindBy(orglang => orglang.language == "en-
US"), couses => couses.couse.orgid, orgid => (param.organizationid > 0 ?
param.organizationid : orgid.orgid), (couses, orgid) => new { couses,
orgid
})
.Join(_GoUoW.Couses_lang.FindBy(couselang => couselang.language == "en-
US"),
organization => organization.orgid.orgid, couselang => couselang.cousesid,
(organization, couselang) => new { organization, couselang })
.Select(x => new
{
x.organization.couses.feather.amount,
x.organization.couses.feather.feathers,
x.couselang.title
//x.organization.orgid.title,
}).ToList();

Search column names and tables

Is there any way to search your database for column names or tables in linqpad. Im looking for a similar feature that you can get in SSMS through red gates sql search.
You can get the table and column names from the Linq mapping. The following should dump out the table and column names.
var columns =
(from t in this.Mapping.GetTables()
from dm in t.RowType.DataMembers
where dm.DbType != null
select new
{
TableName = t.RowType.Name ,
TableSqlName = t.TableName,
dm.DbType,
ColumnName = dm.Name,
dm.IsPrimaryKey,
ColumnSqlName = dm.MappedName
}
);
columns.Dump();
So it should be straightforward to filter this query.
If you enable system tables under properties for your connection you can use a query like this (this is for MS SQL but you can probably adapt it to others)
void Main()
{
var text = "ThingToFind";
SearchColumns(text).Dump("Columns: " + text);
SearchModules(text).Dump("Modules: " + text);
}
#region
IEnumerable<dynamic> SearchColumns(string text)
{
return sys
.columns
.Join(sys.objects, o => o.object_id, i => i.object_id, (o, i) => new { Object = i, Column = o })
.Join(sys.types, o => o.Column.user_type_id, i => i.user_type_id, (o, i) => new { o.Column, o.Object, Type = i })
.Where(c => c.Object.type_desc != "INTERNAL_TABLE")
.Where(c => c.Object.type_desc != "SYSTEM_TABLE")
.OrderBy(c => c.Object.type)
.ThenBy(c => c.Object.name)
.Select(c => new { c.Object, c.Column, c.Type, Default = c.Column.default_object_id != 0 ? sys.default_constraints.Single(d => d.object_id == c.Column.default_object_id).definition : null })
.Select(c => new { Table_Type = c.Object.type_desc, Table = c.Object.name, Name = c.Column.name, Type = c.Type.name, Length = c.Column.max_length, Precision = c.Column.precision, Scale = c.Column.scale, Nullable = c.Column.is_nullable, c.Default })
.AsEnumerable()
.Where(c => c.Name.ContainsIgnoreCase(text));
}
IEnumerable<dynamic> SearchModules(string text, bool findRelatedModules = false)
{
var modules = sys
.sql_modules
.AsEnumerable()
.Join(sys.objects, o => o.object_id, i => i.object_id, (o, i) => new { i.name, definition = o.definition.Trim() })
.ToList();
var result = modules
.Where(m => m.name.ContainsIgnoreCase(text) || m.definition.ContainsIgnoreCase(text))
.ToList();
while (findRelatedModules)
{
var add = result
.SelectMany(r => r.definition.Split(" \t\n\r!##$%^&*()-=+[]{};':\",.<>/?\\|`~".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
.Distinct()
.Where(token => modules.Any(m => m.name.ToLower() == token.ToLower()))
.Where(token => !result.Any(m => m.name.ToLower() == token.ToLower()))
.ToList();
result.AddRange(add.Select(a => modules.Single(m => m.name.ToLower() == a.ToLower())));
findRelatedModules = add.Any();
}
result
.Where(m => !m.definition.ContainsIgnoreCase(m.name))
.Dump("Renamed Modules");
return result.OrderBy(r => r.name);
}
#endregion
public static class StringExtensions
{
public static bool ContainsIgnoreCase(this string source, string toCheck, bool bCaseInsensitive )
{
return source.IndexOf(toCheck, bCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) >= 0;
}
}

Joining tables in NHibernate

I have a query below, How can recreate this one to join the tables that will return a list of SurveyProjectNormDTO using NHibernate? Any help please?
using (var session = OpenSession()){
var projectGroupIds = session.Query<ReportingStructureNodeProjectGroups>()
.Where(x => x.NodeID == nodeId);
projectGroupIds.Fetch(x => x.ProjectGroupID).ToFuture();
var projectIds = session.Query<ProjectGroup>().Where(p => projectGroupIds.Contains(p.Id));
projectIds.Fetch(x => x.ProjectID).ToFuture();
var projectNormProjects = session.Query<SurveyProjectNorm>().Where(x => projectIds.Contains(x.SurveyProjectId));
projectNormProjects.Fetch(x => x.ShortLabels).ToFuture();
projectNormProjects.Fetch(x => x.ReportingNames).ToFuture();
projectNormProjects.Fetch(x => x.NormProject).ToFuture();
var response = new List<SurveyProjectNormDTO>();
projectNormProjects.ToList().ForEach(
p =>
{
response.Add(
new SurveyProjectNormDTO { Id = p.Id, ProjectName = p.NormProject.ProjectName, ReportingName = p.ReportingNames.Select(s => s.LocalizedText).FirstOrDefault() });
});
return response;
I am not sure if these let commands will work fine but you can try this. It will do a single hit on the database fetching the properties. Test it and let us know if it works.
var queryResult = (from p in session.Query<SurveyProjectNorm>()
let projectGroupIds = session.Query<ReportingStructureNodeProjectGroups>().Where(x => x.NodeID == nodeId).Select(x => x.Id)
let projectIds = session.Query<ProjectGroup>().Where(x => projectGroupIds.Contains(x.Id)).Select(x => x.Id)
where projectIds.Contains(p.SurveyProjectId)
select p)
.Fetch(x => x.ShortLabels)
.Fetch(x => x.ReportingNames)
.Fetch(x => x.NormProject)
.ToList();
var response = new List<SurveyProjectNormDTO>();
queryResult.ForEach(p =>
response.Add(new SurveyProjectNormDTO {
Id = p.Id,
ProjectName = p.NormProject.ProjectName,
ReportingName = p.ReportingNames.Select(s => s.LocalizedText).FirstOrDefault() }));
return result;

NHIbernate QueryOver detached criteria and Any clause

I have the following in subquery which is failing:
var subquery = QueryOver.Of<Product>()
.Where(x => x.ProductCategories.Any(y => y.Categgory == parameter.Category));
I get an error for the Any statement:
Unrecognised method call: System.Linq.Enumerable:Boolean Any
How would I update the above restriction for QueryOver?
ProductCategory productCategory = null;
var subquery = QueryOver.Of<Product>()
.JoinAlias(product => product.ProductCategories, () => productCategory)
.Where(() => productCategory.Category.Id == parameter.Category.Id);
What's type of Category? If this is an entity:
productCategory.Category.Id == parameter.Category.Id
If this is base property:
productCategory.Category == parameter.Category
Is it many-to-many relation? (Product and Category)
Category category = null;
var subquery = QueryOver.Of<Product>()
.JoinAlias(product => product.Category, () => category)
.Where(() => category.Id == parameter.Category.Id);
ProductCategory productCategory = null;
var subquery = QueryOver.Of<Product>()
.JoinAlias(product => product.ProductCategories, () => productCategory)
.Where(Subqueries.WhereExists(CatExistsQuery())
private QueryOver<ProductCategory , ProductCategory > CatExistsQuery(<your type> parameter)
{
ProductCategory _innerCat = null;
var query = (QueryOver<ProductCategory , ProductCategory >)Session
.QueryOver(() => _innerCat )
.Where(() => _productCategory.Id== _innerCat.Id)
.And (innerCat.Id == parameter.Category.Id)
return query ;
}

QueryOver by join and add conditions by Independent if

I have a QueryOver by JoinQueryOver In Nhibernate 3.1
The Person class has a association by Identity class (one-to-one)
Code is a field of Person class and FirstName is a field of Identity class.
var q = SessionInstance.QueryOver<Person>()
.Where(p => p.Code.IsLike(code,MatchMode.Start))
.Full.JoinQueryOver(p => p.Identity);
if (!String.IsNullOrEmpty(firstName))
q = q.Where(i => i.FirstName.IsLike(firstName, MatchMode.Anywhere));
return q.List<Person>();
that result is correct but, there is a problem. The search does not include items by null value for Code field in Person class. I corrected to following query.
var q = SessionInstance.QueryOver<Person>()
.Full.JoinQueryOver(p => p.Identity);
if (!String.IsNullOrEmpty(Code))
q = q.Where(i => i.Person.Code.IsLike(code, MatchMode.Start));
if (!String.IsNullOrEmpty(firstName))
q = q.Where(i => i.FirstName.IsLike(firstName, MatchMode.Anywhere));
return q.List<Person>();
Now i have a runtime error by this message:
could not resolve property: Identity.Code of: MyNameSpace.Domain.Entities.Identity
in a query by join between two class, How can add two condition(where) by if.
(if parameter != null)
Identity identityAlias = null;
var q = SessionInstance.QueryOver<Person>()
.Full.JoinAlias(p => p.Identity, () => identityAlias);
if (!String.IsNullOrEmpty(code))
q.Where(p => p.Code.IsLike(code, MatchMode.Start));
if (!String.IsNullOrEmpty(firstName))
q.Where(() => identityAlias.FirstName.IsLike(firstName, MatchMode.Anywhere));
or
var q = SessionInstance.QueryOver<Person>();
if (!String.IsNullOrEmpty(code))
q.Where(p => p.Code.IsLike(code, MatchMode.Start));
if (!String.IsNullOrEmpty(firstName))
q.Full.JoinQueryOver(p => p.Identity)
.Where(i => i.FirstName.IsLike(firstName, MatchMode.Anywhere));