C# 如何使用nHibernate和QueryOver API获得不同的结果?
我有这个存储库方法C# 如何使用nHibernate和QueryOver API获得不同的结果?,c#,nhibernate,queryover,C#,Nhibernate,Queryover,我有这个存储库方法 public IList<Message> ListMessagesBy(string text, IList<Tag> tags, int pageIndex, out int count, out int pageSize) { pageSize = 10; var likeString = string.Format("%{0}%", text); var query = sessi
public IList<Message> ListMessagesBy(string text, IList<Tag> tags, int pageIndex, out int count, out int pageSize)
{
pageSize = 10;
var likeString = string.Format("%{0}%", text);
var query = session.QueryOver<Message>()
.Where(Restrictions.On<Message>(m => m.Text).IsLike(likeString) ||
Restrictions.On<Message>(m => m.Fullname).IsLike(likeString));
if (tags.Count > 0)
{
var tagIds = tags.Select(t => t.Id).ToList();
query
.JoinQueryOver<Tag>(m => m.Tags)
.WhereRestrictionOn(t => t.Id).IsInG(tagIds);
}
count = 0;
if(pageIndex < 0)
{
count = query.ToRowCountQuery().FutureValue<int>().Value;
pageIndex = 0;
}
return query.OrderBy(m => m.Created).Desc.Skip(pageIndex * pageSize).Take(pageSize).List();
}
但它需要一个属性列表来解决这个截然不同的问题。此消息是我的实体根。是否有办法在不提供所有实体属性的情况下获得此行为
提前感谢,Anders如果您使用的是ICriteria API,您需要:
.SetResultTransformer(new DistinctEntityRootTransformer())
.TransformUsing(Transformers.DistinctRootEntity)
如果您使用的是QueryOver API,则需要:
.SetResultTransformer(new DistinctEntityRootTransformer())
.TransformUsing(Transformers.DistinctRootEntity)
但是要注意,这一切都发生在客户端,所以所有重复的行仍然会被提取。尝试类似的方法
public IPagedList<Client> Find(int pageIndex, int pageSize)
{
Client clientAlias = null;
var query = Session.QueryOver<Client>(() => clientAlias)
.Select(
Projections.Distinct(
Projections.ProjectionList()
.Add(Projections.Property<Client>(x => x.Id).As("Id"))
.Add(Projections.Property<Client>(x => x.Name).As("Name"))
.Add(Projections.Property<Client>(x => x.Surname).As("Surname"))
.Add(Projections.Property<Client>(x => x.GivenName).As("GivenName"))
.Add(Projections.Property<Client>(x => x.EmailAddress).As("EmailAddress"))
.Add(Projections.Property<Client>(x => x.MobilePhone).As("MobilePhone"))
)
)
.TransformUsing(Transformers.AliasToBean<Client>())
.OrderBy(() => clientAlias.Surname).Asc
.ThenBy(() => clientAlias.GivenName).Asc;
var count = query
.ToRowCountQuery()
.FutureValue<int>();
return query
.Take(pageSize)
.Skip(Pagination.FirstResult(pageIndex, pageSize))
.List<Client>()
.ToPagedList(pageIndex, pageSize, count.Value);
}
公共IPagedList查找(int-pageIndex,int-pageSize)
{
客户端clientAlias=null;
var query=Session.QueryOver(()=>clientAlias)
.选择(
投影,清晰(
投影。投影列表()
.Add(projects.Property(x=>x.Id).As(“Id”))
.Add(Projections.Property(x=>x.Name).As(“Name”))
.Add(Projections.Property(x=>x.姓氏).As(“姓氏”))
.Add(projects.Property(x=>x.GivenName).As(“GivenName”))
.Add(Projections.Property(x=>x.EmailAddress).As(“EmailAddress”))
.Add(projects.Property(x=>x.MobilePhone).As(“MobilePhone”))
)
)
.TransformUsing(Transformers.AliasToBean())
.OrderBy(()=>clientAlias.姓氏).Asc
.ThenBy(()=>clientAlias.GivenName).Asc;
变量计数=查询
.ToRowCountQuery()文件
.未来价值();
返回查询
.Take(页面大小)
.Skip(分页.FirstResult(页面索引,页面大小))
.List()
.ToPagedList(页面索引、页面大小、计数值);
}
您可以使用SelectList和GroupBy,例如:
tags.SelectList(t => t.SelectGroup(x => x.Id))
应该工作并生成与distinct相同的查询计划
如果组中需要多个项目,请执行以下操作:
tags.SelectList(t => t.SelectGroup(x => x.Id)
.SelectGroup(x => x.Name)
)
我最近创建了一个基于映射对象类型应用select distinct的方法。 它将此应用于IQueryOver对象(类的属性)。方法还可以访问nhibernate配置。您可以将这些作为方法参数添加。需要为生产工作,但该方法在dev中工作得很好,到目前为止只用于一个实体 创建此方法是因为我试图在服务器级别分页数据,而不同的结果转换器无法工作 获取对象集合(query.List())后,可能需要重新加载对象以填充一对多子对象。多对一映射将被代理用于延迟加载
public void DistinctRootProjectionList<E>()
{
var classMapping = Context.Config.GetClassMapping(typeof(E));
var propertyIterator = classMapping.UnjoinedPropertyIterator;
List<IProjection> projections = new List<IProjection>();
ProjectionList list = Projections.ProjectionList();
list.Add(Projections.Property(classMapping.IdentifierProperty.Name), classMapping.IdentifierProperty.Name);
foreach (var item in propertyIterator)
{
if (item.Value.IsSimpleValue || item.Value.Type.IsEntityType)
{
list.Add(Projections.Property(item.Name), item.Name);
}
}
query.UnderlyingCriteria.SetProjection(Projections.Distinct(list));
query.TransformUsing(Transformers.AliasToBean<E>());
}
public void distinctroutprojectList()
{
var classMapping=Context.Config.GetClassMapping(typeof(E));
var propertyIterator=classMapping.UnjoinedPropertyIterator;
列表投影=新列表();
ProjectionList=Projections.ProjectionList();
添加(Projections.Property(classMapping.IdentifierProperty.Name)、classMapping.IdentifierProperty.Name);
foreach(propertyIterator中的var项)
{
if(item.Value.IsSimpleValue | | item.Value.Type.IsEntityType)
{
列表.添加(投影.属性(项.名称),项.名称);
}
}
query.underyingCriteria.SetProjection(Projections.Distinct(list));
query.TransformUsing(Transformers.AliasToBean());
}
我用来加载一对多关系的代码。。。T是实体类型
for (int i = 0; i < resp.Data.Count; i++)
{
resp.Data[i] = session.Load<T>(GetInstanceIdValue(resp.Data[i]));
}
for(int i=0;i
ICriteria API在QUeryOver方面不是很流畅,但是.TransformUsing(Transformers.distinctroventy);工作完美..TransformUsing(Transformers.distinctroventy)根本不适用于分页:/还有其他想法吗?它不适用于分页。对于分页查询,您将需要使用Projections这是否意味着您不能选择别名并执行不同的操作(因为它们都是转换器,您似乎只能使用一个转换器)?我定期对这个问题进行投票,所以有时会重新讨论。今天没有更好的解决方案了吗?在EF中,这只是工作。(虽然他们还有其他问题)有效,但。。。乏味的您可以调用WithAlias扩展方法,而不是“xxx”,只需稍微少一些神奇的字符串。ThanksWithAlias扩展方法示例:。带别名(()=>entity.PropertyName)