我正在使用Linq-To-NHibernate.我需要使用一些未映射到列的属性.
例如
Repository<Person>
.Find()
.Select(p => new PersonModel() { Id = p.Id, FullName= p.FullName,Position = p.Position });
Run Code Online (Sandbox Code Playgroud)
该位置不是映射属性,它包含一些逻辑.我得到了未映射的属性错误.
谢谢.
NHibernate 试图加载一个小的数据层次结构时遇到了问题。我的域模型如下所示:
class GrandParent
{
int ID{get;set;}
IList<Parent> Parents {get; set;}
}
class Parent
{
IList<Child> Children {get; set;}
}
class Child
{
}
Run Code Online (Sandbox Code Playgroud)
我想为给定的祖父母加载所有父母和孩子。这个 Linq-to-NH 查询创建了正确的 SQL 并按预期加载了 GrandParent:(该示例假设祖父母有 2 个父母,每个父母都有 2 个子对象 - 所以总共有 4 个子对象)。
var linq = session.Linq<GrandParent>();
linq.Expand("Parents");
linq.Expand("Parents.Children");
linq.QueryOptions.RegisterCustomAction(c =>
c.SetResultTransformer(new DistinctRootEntityResultTransformer()));
var grandparent = (select g from session.Linq<GrandParent>()
where g.ID == 1
select g).ToList();
Assert(grandparent.Count == 1); //Works
Assert(grandparent.Parents.Count == 2); //Fails - count = 4!
Run Code Online (Sandbox Code Playgroud)
Grandparent.Parents 集合包含 4 个项目,其中 2 个是重复的。似乎 DistinctRootEntityResultTransformer …
使用NHibernate.Linq时是否可以设置LockMode?使用ICriteria时我可以这样:
var criteria = Session.CreateCriteria<Foo>();
criteria.SetLockMode(LockMode.None);
criteria.Add(Expression.Eq("Title", title));
Run Code Online (Sandbox Code Playgroud)
是否可以使用Nhibernate.Linq构建相同的查询?
我在我的一个项目(和ASP.NET MVC应用程序)中使用Fluent NHibernate,使用LINQ查询数据(使用LINQ到NHibernate库).
更改了对象名称以保护无辜者.
假设我在数据库(MySQL)中有以下类Foo,Bar,Baz及其相应的表.
Foo与Fluent映射中定义的Bar(表"FooBar")和Baz(表"FooBaz")有多对多的关系.因此,类接口定义如下:
public class Foo {
public virtual int id { get; set; }
public virtual string name { get; set; }
public virtual string email { get; set; }
public virtual IList<Bar> bars { get; set; }
public virtual IList<Baz> bazes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常标准的课程.我们可以看到一个Foo对象将有一个条形和bazes列表.
尝试执行LINQ查询时出现问题.
如果我这样做一个简单的查询,它工作正常(where子句不重要):
var foos = from foo in session.Linq<Foo>()
where email.equals("foo@bar.com")
select foo;
IList<Foo> listFoos = foos.ToList();
Run Code Online (Sandbox Code Playgroud)
这将返回一个Foos列表,其中填充了所有字段(id,name,email,bars,bazes).log4net显示NHibernate对集合执行单独的查询.
当我只想加载一些字段时出现问题.例如,我可能只想加载查询中的条形,而不是bazes.
此查询编译,但在运行时产生错误:
var foos = from foo in session.Linq<Foo>()
where …Run Code Online (Sandbox Code Playgroud) 这是问题所在:简而言之,我使用了comb.guid身份策略,我需要在保存的标记之后创建的所有行.
这是我想要得到的虚拟代码示例:
return session.Linq .Where(p => p.Id.CompareTo(lastSyncedEntityIdentity)== 1).ToList();
这引发了一个异常,说没有实现CompareTo ......
System.NotImplementedException occurred
Message=The method CompareTo is not implemented.
Source=NHibernate.Linq
StackTrace:
at NHibernate.Linq.Visitors.RootVisitor.VisitMethodCall(MethodCallExpression expr) in e:\horn\.horn\orm\nhcontrib\nhibernate.linq\Working-2.1\src\NHibernate.Linq\Visitors\RootVisitor.cs:line 97
InnerException:
Run Code Online (Sandbox Code Playgroud)
正如你从堆栈中看到的那样,我在没有任何帮助的情况下尝试了来自hornget trunk的2.1版本
任何提示/线索我必须做什么才能绕过这个限制,我想这会影响大多数人使用comb.guid策略?
谢谢,尼古拉
我刚刚下载了NHibernate的Linq提供程序,我只是有点兴奋.但我不太了解Linq语法.
我可以从这样的查询中返回整个对象:
var query = from foo in session.Linq<Kctc.BusinessLayer.Domain.Case>()
where foo.CaseNumber > 0
select foo;
Run Code Online (Sandbox Code Playgroud)
我可以选择这样一个属性:
var query = from foo in session.Linq<Kctc.BusinessLayer.Domain.Case>()
where foo.CaseNumber > 0
select foo.Id;
Run Code Online (Sandbox Code Playgroud)
但是我如何选择两个属性,例如foo.Id和foo.Bar?或者那是不可能的?
谢谢
大卫
我目前的项目是使用NHibernate 3.0b1和NHibernate.Linq.Query<T>()API.我对LINQ非常流利,但我对HQL或ICriteria API没有任何经验.IQueryable API不支持我的一个查询,因此我认为我需要使用以前的API之一 - 但我不知道从哪里开始.
我已经尝试在网上搜索ICriteria的一个很好的"入门"指南,但我发现的唯一例子要么太简单了,要么在这里申请,要么太高级我无法理解.如果有人有一些好的学习材料可以传递,我们将不胜感激.
在任何情况下,我要查询的对象模型看起来像这样(大大简化,省略了非相关属性):
class Ticket {
IEnumerable<TicketAction> Actions { get; set; }
}
abstract class TicketAction {
Person TakenBy { get; set; }
DateTime Timestamp { get; set; }
}
class CreateAction : TicketAction {}
class Person {
string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
A Ticket有一个TicketAction描述其历史的集合.TicketAction亚型包括CreateAction,ReassignAction,CloseAction等所有的门票已经一CreateAction创建时添加到此集合.
此LINQ查询正在搜索具有给定名称的人创建的票证.
var createdByName = "john".ToUpper();
var tickets = _session.Query<Ticket>()
.Where(t => t.Actions
.OfType<CreateAction>() …Run Code Online (Sandbox Code Playgroud) 我试图基于外键过滤集合.我有两个映射的类
public class GroupPriceOverrideMap:ClassMap<GroupPriceOverride>
{
public GroupPriceOverrideMap()
{
CompositeId()
.KeyReference(x => x.Service,"ServiceCode")
.KeyReference(x => x.CustomerAssetGroup, "GroupID");
Map(x => x.Price);
Table("accGroupPriceOverride");
}
}
public class CustomerAssetGroupMap:ClassMap<CustomerAssetGroup>
{
public CustomerAssetGroupMap()
{
Id(x => x.GroupID).Unique();
Map(x => x.Description);
References(x => x.Customer).Column("CustomerID");
HasMany<GroupPriceOverride>(x => x.PriceOverrides).KeyColumn("GroupID");
Table("accCustAssetGroup");
}
}
Run Code Online (Sandbox Code Playgroud)
我用它来查询它
_session.Linq<GroupPriceOverride>.Where(x => x.CustomerAssetGroup.GroupID == groupID)
Run Code Online (Sandbox Code Playgroud)
然而,这是产生
SELECT this_.ServiceCode as ServiceC1_9_0_, this_.GroupID as GroupID9_0_, this_.Price as Price9_0_ FROM accGroupPriceOverride this_ WHERE customeras1_.GroupID = @p0
Run Code Online (Sandbox Code Playgroud)
where子句引用了一个不存在的表别名(customeras1).这可能是与customerassetgroup交叉的别名,但不需要执行该交叉.我确信它只是我的映射中的某些内容是错误的但我找不到它.我已经尝试过各种列重命名,以防两个表中存在GroupID导致问题但是没有修复它.有任何想法吗?
编辑 我发现,如果我查询做
_session.Linq<CustomerAssetGroup>().Where(x => x.GroupID == groupID).FirstOrDefault().PriceOverrides;
Run Code Online (Sandbox Code Playgroud)
然后我得到了正确的结果.我还发现,如果我救了一个GroupPriceOverride,然后使用HQL那么就不会被发现,但我仍然可以通过加载父并查看其集合覆盖的找到实体查询它.
_session.CreateQuery("FROM GroupPriceOverride i").List().Count;//returns …Run Code Online (Sandbox Code Playgroud) 我使用NHibernate查询我的数据库.现在我需要使用谓词来限制所选择的数据.到目前为止,我发现(Google驱动开发的最佳状态)使用Expressions和NHibernate.Linq可以实现这样的功能.
这是我试过的:
public IList<Bestellung> GetAll(Predicate<Order> predicate)
{
Expression<Func<Order, bool>> restriction = x => predicate(x);
ISession session = SessionService.GetSession();
IList<Order> bestellungen = session.Query<Order>()
.Where(restriction).ToList();
return bestellungen;
}
Run Code Online (Sandbox Code Playgroud)
这导致无法将类型为'NHibernate.Hql.Ast.HqlCast'的对象强制转换为'NHibernate.Hql.Ast.HqlBooleanExpression'.只需快速检查它的位置:将方法体的第一行更改为
Expression<Func<Order, bool>> restriction = x => x.Id!=1;
Run Code Online (Sandbox Code Playgroud)
令人惊叹的结果是一切正常.
如何在表达式中执行我的Predicate?
我需要一种方法来在Nhibernate中查询具有包含值的Dictionary属性的项目.
假设:
public class Item
{
public virtual IDictionary<int, string> DictionaryProperty {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
和映射:
public ItemMap()
{
HasMany(x => x.DictionaryProperty)
.Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
.AsMap<string>(
index => index.Column("IDNumber").Type<int>(),
element => element.Column("TextField").Type<string>().Length(666)
)
.Cascade.AllDeleteOrphan()
.Fetch.Join();
}
Run Code Online (Sandbox Code Playgroud)
我想查询所有Item具有字典值"SomeText"的s.Linq中的以下示例失败:
session.Query<Item>().Where(r => r.DictionaryProperty.Any(g => g.Value == "SomeText"))
Run Code Online (Sandbox Code Playgroud)
有错误
cannot dereference scalar collection element: Value
Run Code Online (Sandbox Code Playgroud)
那么在NHibernate中有没有办法实现这一点?Linq不是独家要求,而是优先考虑.并不是说我对查询可以使用的字典键不感兴趣.ContainsKey.Φορ 这是相似但不相同的
nhibernate fluent-nhibernate linq-to-nhibernate nhibernate-criteria