我有以下两个对象:
用户
class User {
public int role;
}
角色
class Role {
public int id;
public string name;
}
请注意role
内的User
属性为int
而非Role
,这是我们的限制。
我想加入所有用户和他的每个角色。在映射对象中没有您可以理解的引用,只是一个简单的类型(int
)。
我该如何进行加入声明?
答案 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属性。