【问题标题】:NHibernate Subquery Linq - How to select groups that contain a certain item by idNHibernate Subquery Linq - 如何通过 id 选择包含某个项目的组
【发布时间】:2010-02-25 15:46:04
【问题描述】:

短版 此查询在数据库中有效,但在 Linq To NHibernate 中失败。为什么?

var items = (from g in db.Find<DataGroupInfo>() 
              where (from d in g.data where d.Id == dataID select d).Count() > 0  
              select g).ToList();

详细长版

我有两个由 NHibernate Automapper 映射的具有多对多关系的对象。

return Fluently.Configure()
     //a few other settings here...
     //relevant settings below
               .Override<DataGroupInfo>(map =>
               {
                   map.HasManyToMany(d => d.data);
               }
               .Conventions.Add(DefaultCascade.All())
               .Conventions.Add(DefaultLazy.Never())


public class DataInfo
{
    public virtual int Id { get; private set; }
    public virtual DateTime created { get; set; }
    public virtual string label { get; set; }
    public virtual string description { get; set; }
}

public  class DataGroupInfo
{
    public virtual Int32 Id { get; set; }

    public virtual DateTime created { get; set; }
    public virtual string label { get; set; }
    public virtual string description { get; set; }

    public virtual IList<DataInfo> data { get; set; }
}

我想获取所有包含某个 DataInfo 的 DataGroup。

此查询在 SQLite 管理员中有效,因此我认为我的数据库设置正确:

select * from DataGroupInfo
INNER JOIN DataInfoToDataGroupInfo ON
DataGroupInfo.Id ==  DataInfoToDataGroupInfo.DataGroupInfo_id
where
DataInfoToDataGroupInfo.DataInfo_id == 3

我是通过这两种方式暴露Linq的仓库

public IQueryable<T> Find<T>()
{
    return session.Linq<T>();
}

public IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate)
{
    return Find<T>().Where(predicate);
}

我使用这样的存储库

  static public List<DataGroupInfo> GetAllWithData(Int32 dataID)
    {
        using (var db = new DBRepository())
        {
            //var items = (from g in db.Find<DataGroupInfo>() 
            //                where (from d in g.data where d.Id == dataID select d).Count() > 0  
            //             select g).ToList();

            var items = db.Find<DataGroupInfo>(dg => dg.data.Where(d => d.Id == dataID).Count() > 0 ).ToList();

            return items;
        }
    }

当 Linq 尝试执行上述任何一种方法时,我都会收到以下错误:

NHibernate.QueryException 是 用户代码未处理
Message="无法解析属性: data.Id 的: MapLarge.Public.Data.DataGroupInfo"
来源=“NHibernate”堆栈跟踪: 在 NHibernate.Persister.Entity.AbstractPropertyMapping.GetColumns(字符串 属性名)

我做错了什么?

----更新-----

这种解决方法给出了预期的结果,但它是一种强力方法,将每个数据组拉入内存,然后使用 c# 而不是数据库过滤对象。但至少它将我的问题缩小到 NHibernate 特定问题。

        var step1 = db.Find<DataGroupInfo>().ToList();
        var items = step1.Where(dg => dg.data.Where(d => d.Id == dataID).Count() > 0).ToList();

如果有人在场,我仍然很想得到答案:-)

【问题讨论】:

  • 您的 DataInfoToDataGroupInfo 表是什么样的?当链接表包含两个外键以外的列时,我遇到了 Automapper 加入多对多的问题。
  • DataInfoToDataGroupInfo 只有两个外键,整个数据库实际上是由 Nhibernate AutoMapper 创建的,所以我认为如果我的类定义符合 NHibernate Automapper 约定,它应该是可靠的。下面是我在外部检查表时 SQLite 管理员显示的表属性: ColumnInfoToColumnGroupInfo ColumnGroupInfo_id INTEGER not null ColumnInfo_id INTEGER not null 这是自动生成代码: var newDB = new SchemaExport(config).Create(true, true);
  • 我知道 Linq to NHibernate 是相当新的,也许这是一个错误或不支持的查询类型?

标签: c# sql linq nhibernate linq-to-nhibernate


【解决方案1】:

LINQ-to-NHibernate 当前不支持子查询或联接:http://ayende.com/Blog/archive/2009/07/26/nhibernate-linq-1.0-released.aspx

【讨论】:

  • 谢谢。我以为我记得这样的限制,但不确定自去年夏天以来该限制是否发生了变化。当该功能起作用时很好。
  • 我知道他们一直在努力支持所有 101 个 Linq 示例。 msdn.microsoft.com/en-us/vcsharp/aa336746.aspx 如果 Ayende 的博客或 NHibernate Wiki 保留 101 个样本列表中受支持和不受支持的 Linq 样本列表,那就太酷了。我认为他已经为他的单元测试中的每个内置测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
相关资源
最近更新 更多