标签: linq-to-nhibernate

如何异步运行NHibenate查询?

提高服务器应用程序可伸缩性的一种方法是异步运行IO绑定操作(读取文件,套接字,Web请求,数据库请求等).这并不意味着在ThreadPool中运行它们,它只会在执行操作时阻塞线程.正确的方法是使用异步API(BeginRead,BeginGetResponse,BeginExecuteReader等).这个问题在CLR vi C# book中有详细描述.

这是一篇关于Linq to SQL中的异步查询的文章.

是否有任何方法可以异步执行Nhibernate查询?怎么样Linq到NHibernate?

谢谢,安德烈

.net nhibernate asynchronous linq-to-nhibernate

20
推荐指数
4
解决办法
1万
查看次数

当"WHERE IN()"有数千个值时,如何使用Nhibernate检索数据?(sql中的参数太多)

问题:Nhibernate解析"WHERE IN()"sql中的每个值作为参数,MS SQL服务器不支持足够的参数(超过2000).

我正在使用Nhibernate和Linq来从SQL服务器中检索我的数据,我需要根据已知的ID加载很多实体.

我的代码看起来像这样:

int[] knownIds = GetIDsFromFile();
var loadedEntities = _Repository.GetAll()
                                .Where(x => knownIds.Contains(x.ID))
                                .ToList();
Run Code Online (Sandbox Code Playgroud)

哪个给出这样的sql:

SELECT id, name FROM MyTable 
WHERE id IN (1 /* @p0 */,2 /* @p1 */,3 /* @p2 */,4 /* @p3 */, 5 /* @p4 */)
Run Code Online (Sandbox Code Playgroud)

如果knownIds中的太多,那么这段代码将抛出异常,因为NHibernate使用了许多参数.

我认为最好的解决方案是如果我能让NHibernate只为整个"WHERE IN()"使用1个参数,但我不知道如何做到这一点:

SELECT id, name FROM MyTable WHERE id IN (1, 2, 3, 4, 5 /* @p0 */)
Run Code Online (Sandbox Code Playgroud)

我很高兴听到有关如何解决这个问题的任何想法 - 通过扩展LINQ提供程序或通过其他方式.一个解决方案是简单地执行查询x次(knownIds.Count/1000),但我更想要一个适用于我所有实体的通用解决方案.

我试图通过搜索谷歌和Stackoverflow来扩展LINQ提供程序,但我找不到解决方案,我没有任何经验与HQL或treebuilder.这里有一些我去过的网站:

更新: 我知道在IN子句中有这么多的值是不好的做法,但我不知道我想要做的更好的解决方案.
考虑一家公司,每个月,所有客户都会为公司的服务付费一次.该公司本身不处理付款,但有另一家公司来收钱.公司每个月都会收到一个包含这些付款状态的文件:如果已付款或未付款.该文件仅包含特定付款的ID,而不包含客户的ID.一家拥有3000名月度客户的公司每月将进行3000次LogPayments,其状态需要更新.1年后将会有大约36,000个LogPayments,所以加载它们似乎也不是一个好的解决方案.

我的解决方案: …

.net c# linq nhibernate linq-to-nhibernate

20
推荐指数
1
解决办法
8867
查看次数

LINQ Fluent NHIBERNATE .Contains()在QueryOver <>中不起作用,但在Query <>中起作用

使用FNH,我尝试使用以下方法检索类别:

_session.QueryOver<Data.Model.Category>()
                                     .Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
                                     .List()
                                     .Select(_categoryMapper.CreateCategory)
                                     .ToList();
Run Code Online (Sandbox Code Playgroud)

但是我在.Contains()方法中遇到错误:

无法识别的方法调用:System.Collections.Generic.ICollection`1 [[System.Int64,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]:Boolean包含(Int64)

为什么我得到那个错误,出了什么问题?

我浏览了一些帖子,然后将查询更改为(下面),这适用于Query <>.

_session.Query<Data.Model.Category>()
                                     .Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
                                     .ToList()
                                     .Select(_categoryMapper.CreateCategory)
                                     .ToList();
Run Code Online (Sandbox Code Playgroud)

我认为QueryOver <>是最新的和最好的,应该使用而不是Query <>.

我使用如上所示的QueryOver <>的方式有什么问题?

nhibernate fluent-nhibernate linq-to-nhibernate

19
推荐指数
2
解决办法
1万
查看次数

了解NHibernate + Linq + Future

我想在编写Linq查询时使用NHibernate进行分页.做这样的事情很容易:

return session.Query<Payment>()
    .OrderByDescending(payment => payment.Created)
    .Skip((page - 1)*pageSize)
    .Take(pageSize)
    .ToArray();
Run Code Online (Sandbox Code Playgroud)

但有了这个,我没有得到任何关于项目总数的信息.如果我只是做一个简单的.Count(),那将生成一个对数据库的新调用.

我发现这个答案通过使用未来来解决它.但它使用Criteria.我怎么能用Linq做到这一点?

linq nhibernate linq-to-nhibernate

18
推荐指数
1
解决办法
1万
查看次数

如何在我的抽象存储库中包装Linq2NHibernate的.Fetch和.ThenFetch?

我正在使用一个暴露IQueryable<T>这样的通用存储库:

public IQueryable<T> AllEntities
{
    get
    {
        return session.Query<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以像这样查询:

var results =
    (from e in repository.AllEntities
     where e.SomeProperty == "some value"
     select e).ToList();
Run Code Online (Sandbox Code Playgroud)

但是,如果T有父母和祖父母实体并且我想急切地加载它们,我必须这样做:

var results =
    (from e in repository.AllEntities
     where e.SomeProperty == "some value"
     select e)
    .Fetch(x => x.Parent)
    .ThenFetch(x => x.Grandparent)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

这工作,但.Fetch.ThenFetch都Linq2Nhibernate特定扩展方法,这是造成两个问题:

  1. 我必须using NHibernate.Linq;在我的文件顶部包含一个声明.但是,在我正在进行此查询时,它应该是与实现无关的.

  2. 当我尝试对此进行单元测试时,.Fetch和我的模拟存储库提供的.ThenFetch方法相比,和方法失败IQueryable<T>了.

如何将这些内容包装在我的IRepository<T>界面内或某些通用扩展方法中?

更新:

到目前为止,我所提出的是将其添加到我的存储库界面:

IQueryable<T> EagerLoadParent<U>(IQueryable<T> query, 
    Expression<Func<T, U>> parentExpression);
IQueryable<T> …
Run Code Online (Sandbox Code Playgroud)

repository linq-to-nhibernate eager-loading

15
推荐指数
1
解决办法
2804
查看次数

LINQ to Nhibernate重复连接

我有这样的查询

var orderedQueryable = this.participationRequests
           .Fetch(x => x.CommunityEvent)
           .Fetch(x => x.CommunityMember)
                .ThenFetch(x => x.User)
           .Where(x => x.CommunityMember.Community.Id == communityId)
           .OrderBy(x => x.CreateDate);
Run Code Online (Sandbox Code Playgroud)

由于此错误,where子句需要在获取之后.问题是thouse Fetch调用发出额外的连接.在SQL查询中,如下所示:

select *
from   ParticipationRequests participat0_
       left outer join CommunityEvents communitye1_
         on participat0_.CommunityEventId = communitye1_.Id
       left outer join CommunityMembers communitym2_
         on participat0_.CommunityMemberId = communitym2_.Id
       left outer join Users user3_
         on communitym2_.UserId = user3_.Id
       inner join CommunityMembers communitym4_
         on participat0_.CommunityMemberId = communitym4_.Id
       inner join CommunityMembers communitym5_
         on participat0_.CommunityMemberId = communitym5_.Id
       inner join Communities community6_
         on …
Run Code Online (Sandbox Code Playgroud)

.net c# linq nhibernate linq-to-nhibernate

15
推荐指数
1
解决办法
869
查看次数

NHibernate LINQ是否支持Where()子句中的ToLower()?

我有一个实体及其映射:

public class Test
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
}

public class TestMap : EntityMap<Test>
{
    public TestMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Description);
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试对它运行查询(将其从数据库中取出):

var keyword = "test" // this is coming in from the user
keyword = keyword.ToLower(); // convert it to all lower-case

var results = session.Linq<Test>
    .Where(x => x.Name.ToLower().Contains(keyword));

results.Count(); …
Run Code Online (Sandbox Code Playgroud)

linq nhibernate linq-to-nhibernate

14
推荐指数
2
解决办法
3090
查看次数

NHibernate Linq Query比HQL慢3倍

我有一个简单的测试,运行查询5000次.查询的linq版本占用HQL的3倍,缓存的Linq版本比HQL的缓存版本慢得多

HQL:

session.CreateQuery(String.Format("from Episode where SeriesId='{0}' and SeasonNumber='{1}' and EpisodeNumber='{2}'", seriesId, seasonNumber, episodeNumber))
               .SetMaxResults(1)
               .SetCacheable(true)
               .UniqueResult<Episode>();
Run Code Online (Sandbox Code Playgroud)

LINQ:

session.Query<Episode>()
       .Where(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber && c.EpisodeNumber == episodeNumber)
       .Cacheable()
       .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

结果如下

HQL:   Cached: less than a second   No-Cache: 5 seconds
LINQ:  Cached: 8 seconds            No-Cache: 15 seconds

我只是想确保我遇到了预期的开销,而不是我做错了什么.

如果那个头顶在那里并且我可以做的不多,你能否建议一个中间地带,这将需要更少的字符串,但提供更好的性能?

注意:我在Fluent Nhibernate中的缓存设置 .Cache(c => c.UseQueryCache().UseSecondLevelCache().UseMinimalPuts().ProviderClass<HashtableCacheProvider>())

.net nhibernate hql nhibernate.search linq-to-nhibernate

14
推荐指数
1
解决办法
2423
查看次数

如何为NHibernate LINQ语句设置超时

我正在使用Fluent NHibernate进行ORM.在这样做的过程中,我尝试使用NHibernate LINQ语法以LINQ的强大功能获取一组数据.我已经正常工作并执行的代码,例外情况是,如果运行时间超过大约30秒,则会引发超时.我的问题是如何通过NHibernate扩展LINQ语句的默认30秒超时?

我已经在这里,这里这里看过帖子,但前两个是指设置DataContext的Timeout属性,这里不适用,第三个是指用XML设置超时,这也不适用因为我正在使用流畅的NHibernate可以动态生成XML.不仅如此,这篇文章还有2年历史,而Fluent NHibernate自此改变了.

使用ICriteria对象甚至是HQL,我可以指定超时,但这不是目标.我想知道如何设置相同的超时并使用LINQ.

示例代码:

    using (var session = SessionFactory.OpenSession())
    using (var transaction = session.BeginTransaction())
    {
        var query = (from mem in session.Query<Member>()
                     select mem);
        query = query.Where({where statement});
        int start = (currentPage - 1) * max);
        if (start > 0)
            query = query.Skip(start).Take(max);
        else
            query = query.Take(max);

        var list = query.ToList();
        transaction.Commit();
        return list;
    }
Run Code Online (Sandbox Code Playgroud)

此代码(where语句无关紧要)适用于所有目的,除非发生超时.

任何帮助表示赞赏.提前致谢!

linq-to-nhibernate c#-4.0

13
推荐指数
2
解决办法
8461
查看次数

如何在linq-to-Nhibernate中使用多个条件的连接

我有两个类(Request&RequestDetail).我需要Linq To NHibernate通过join在两个类之间进行查询.

var q = SessionInstance.Query<Request>()
       .Where(x => x.State == "Init");

var q2 = SessionInstance.Query<RequestDetail>();
q2 = q2.Where(xx => xx.Purpose.Contains("Purpose Sample")); // This line has a error When execution ??`q.ToList()?`

q = q.Join(q2, request => request.Id, detail => detail.Id, (request, detail) => request);

return q.ToList();
Run Code Online (Sandbox Code Playgroud)

当我添加Where条件时q2,Result有一个运行时错误.异常消息是:Specified method is not supported.

堆栈跟踪 :

   at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource)
   at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree)
   at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()
   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor …
Run Code Online (Sandbox Code Playgroud)

c# linq nhibernate join linq-to-nhibernate

13
推荐指数
2
解决办法
1万
查看次数