在NHibernate中不使用映射连接表
本文关键字:映射 连接 NHibernate | 更新日期: 2023-09-27 18:05:22
我有以下两个对象:
用户class User {
public int role;
}
class Role {
public int id;
public string name;
}
请注意,User
中的role
属性是int
而不是Role
,这是我们的局限性。
我想在所有用户和他的每个角色之间进行连接。在映射对象中,你可以理解没有引用,只有一个简单的类型(int
)。
如何执行join语句?
这叫做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属性
是的,这个" θ连接"(我刚学会这个术语)非常方便,我们不用担心放入无意义的映射关系。
警告,但是在使用这个!!这让我犯了很多错。
加上上面的例子…
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();
这将爆炸一些不支持的异常。诀窍在于任何来自NHibernate Session的东西都必须是LAST。所以这个修改将工作:
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();
说到这里,假设你有一个方法它有一些动态条件。在这个例子中,"list"可能是要筛选的角色列表,但如果列表不存在,则根本不进行筛选。好吧,如果您执行.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 { .. }
部分执行时会失败。我无法解释。在我们的例子中,逻辑只是将一个int的DB值转换为一个模型的Enumerator。但为了解决这个问题,我只是在读取数据时避免进行转换,但保存了值。然后在后面的步骤中,在加载数据之后,我在另一个LINQ语句中进行转换。免责声明:虽然我在过去的几个星期里写了很多这样的东西,但我并没有把这些代码放入我的编译器中进行100%的验证。