gpt4 book ai didi

c# - LINQ-NHibernate - 只为复杂对象选择几个字段(包括集合)

转载 作者:太空狗 更新时间:2023-10-29 22:35:12 25 4
gpt4 key购买 nike

我在我的一个项目(和 ASP.NET MVC 应用程序)中使用 Fluent NHibernate,使用 LINQ 查询数据(使用 LINQ to NHibernate 库)。

更改对象名称以保护无辜者。

假设我在数据库 (MySQL) 中有以下类 Foo、Bar、Baz 及其相应的表。

Foo 与 Fluent 映射中定义的 Bar(表“FooBar”)和 Baz(表“FooBaz”)具有多对多关系。因此,类接口(interface)定义如下:

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; }
}

这是一个非常标准的类。我们可以看到一个 Foo 对象将有一个 bars 和 bazes 的列表。

尝试执行 LINQ 查询时出现问题。

如果我做一个像这样的简单查询,它工作正常(where 子句不重要):

var foos = from foo in session.Linq<Foo>()
where email.equals("foo@bar.com")
select foo;

IList<Foo> listFoos = foos.ToList();

这将返回一个 Foos 列表,其中填充了所有字段(id、name、email、bars、bazes)。 log4net 显示 NHibernate 对集合执行单独的查询。

当我只想加载一些字段时,问题就出现了。例如,我可能只想加载查询中的条形图,而不是 bazes。

此查询编译,但在运行时产生错误:

var foos = from foo in session.Linq<Foo>()
where email.equals("foo@bar.com")
select new Foo()
{
id = foo.id,
name = foo.name,
email = foo.email,
bars = foo.bars
};

IList<Foo> listFoos = foos.ToList();

我得到的错误类似于数组索引越界异常。堆栈跟踪显示了一些与 LINQ-NHibernate 端的集合处理相关的方法名称,但仅此而已。 log4net 报告的查询没有显示对柱状图进行查询的迹象,这意味着在它有时间执行查询以选择柱状图之前发现了一个错误。

有没有人遇到过这种问题?你是怎么解决的?我不想每次在我的应用程序中打开网页时都必须选择所有对象!

谢谢!

编辑:根据要求,这里是堆栈跟踪。

System.IndexOutOfRangeException: L'index se trouve en dehors des limites du tableau. (read: "Index is out of bounds for the array.")

[IndexOutOfRangeException: L'index se trouve en dehors des limites du tableau.]
NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.InvokeMemberInitExpression(MemberInitExpression expression, Object[] args, Int32& argumentCount) +404
NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.TransformTuple(Object[] tuple, String[] aliases) +150

[QueryException: could not instantiate: Foo]
NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.TransformTuple(Object[] tuple, String[] aliases) +265
NHibernate.Loader.Criteria.CriteriaLoader.GetResultColumnOrRow(Object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session) +171
NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) +330
NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +704
NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +70
NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +111
NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +18
NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) +79
NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) +407
NHibernate.Impl.CriteriaImpl.List(IList results) +41
NHibernate.Impl.CriteriaImpl.List() +35
NHibernate.Linq.<GetEnumerator>d__0.MoveNext() +71
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +7665172
System.Linq.Enumerable.ToList(IEnumerable`1 source) +61
FooRepository.List(Int32 count) in C:\...\FooRepository.cs:38
FooController.List() in C:\...\FooController.cs:30
lambda_method(ExecutionScope , ControllerBase , Object[] ) +39
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +178
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +24
System.Web.Mvc.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7() +52
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +254
System.Web.Mvc.<>c__DisplayClassc.<InvokeActionMethodWithFilters>b__9() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +192
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399
System.Web.Mvc.Controller.ExecuteCore() +126
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

最佳答案

一些建议...

首先,NHibernate 默认为延迟加载,因此可能甚至不需要执行您正在尝试的更“高效”的查询。

其次,以下代码并没有完全完成您的示例代码所做的工作 - 它创建了一个名为 miniFoos 的匿名类型列表,其中包含 Foo 中字段的子集。但最终效果与您似乎正在尝试的相似。它还使用我认为称为 LINQ 方法语法的东西。

我在我自己的应用程序中的一个实体上测试了它,它也有一个 IList 属性,它确实有效(尽管我应该注意到我目前正在使用预加载)。我只是剪切并粘贴了工作代码并替换了您示例的名称。

        using( var session = sessionFactory.OpenSession() )
{
session.BeginTransaction();

var foos =
session.CreateCriteria(typeof(Foo))
.List<Foo>();

var miniFoos =
foos.Select(f => new { f.email, f.bars })
.Where(f => f.email.Equals("foo@bar.com)
.ToList();

session.Close();
}

关于c# - LINQ-NHibernate - 只为复杂对象选择几个字段(包括集合),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2007038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com