在没有映射的情况下在NHibernate中连接表

时间:2014-05-26 08:32:07

标签: c# .net nhibernate

我有以下两个对象:

用户

class User {
    public int role;
}

角色

class Role {
    public int id;
    public string name;
}

请注意role内的User属性为int而非Role,这是我们的限制。

我想加入所有用户和他的每个角色。在映射对象中没有您可以理解的引用,只是一个简单的类型(int)。

我该如何进行加入声明?

2 个答案:

答案 0 :(得分:2)

是的,这是" theta join" (因为我刚学过这个术语)非常方便,让我们不要担心放置毫无意义的映射关系。

警告尽管如此使用!!!这让我大吃一惊。

添加上面的例子......

var list = new List<int>( { 2, 3 } ); // pretend in-memory data from something.
var a = 
   (from u in session.Query<User>()
    from x in list
    from r in session.Query<Role>()
    where u.role == r.id
    where r.id == x.id  // pretend list wants to limit to only certain roles.
    select new { u.Username, Role = r.name }).ToList();

这将导致BOMB出现一些NotSupported异常。 诀窍是来自NHibernate Session的任何东西都必须最后。所以这种改变将起作用:

var a = 
   (from x in list
    from u in session.Query<User>()
    from r in session.Query<Role>()
    where u.role == r.id
    where r.id == x.id  // pretend list wants to limit to only certain roles.
    select new { u.Username, Role = r.name }).ToList();

而且顺便说一下,你也可以使用join,但是你必须确保你是否有任何可以为空的数据类型,如果你要加入一些不可为空的东西,你可以使用.Value。

var a = 
   (from x in list
    from u in session.Query<User>()
    join r in session.Query<Role>() on u.role equals r.id
    where r.id == x.id  // pretend list wants to limit to only certain roles.
    select new { u.Username, Role = r.name }).ToList();

虽然我们正在研究它,但是我们说你有一种具有某种动态条件的方法。在此示例中,&#39;列表&#39;这可能是要过滤的角色列表,但如果列表不存在则根本不进行过滤。好吧,如果您执行.ToList(),那么您将立即执行此查询。但是你可以添加一个条件,然后再执行它:

var a = 
    from u in session.Query<User>()
    join r in session.Query<Role>() on u.role equals r.id
    where r.id == x.id  // pretend list wants to limit to only certain roles.
    select new { u.Username, Role = r.name, RoleID = r.id }; // Adding the Role ID into this output.

if (list != null) // assume if the list given is null, that means no filter.
{
    a = a.Where(x => list.Contains(x.RoleID));

    // WARNING. Unfortunately using the "theta" format here will not work. Not sure why.
}

var b = a.ToList(); // actually execute it.
var c = a.Select(x => new { x.Username, x.Role }).ToList() // if you insist on removing that extra RoleID in the output.

最后一件事......有些简单的逻辑在select new { .. }部分执行时会失败。我没有解释。在我们的例子中,逻辑只是将uint的DB值转换为模型的Enumerator。但为了解决这个问题,我只是避免在读取数据时进行转换但保存了价值。然后在后面的步骤中,在加载数据之后,我只是在另一个LINQ语句中进行了转换。

免责声明:虽然过去几周我写了很多这些东西,但我没有把这些代码放到我的编译器中来验证100%。

答案 1 :(得分:1)

它被称为theta join:

var a = (from u in session.Query<User>()
        from r in session.Query<Role>()
        where u.role == r.id
        select new { u.Username, Role = r.name }).ToList();

假设您在User类上有Username属性。