2011-09-28 277 views
3

因为我刚刚开始使用LINQToEntities,Entity Framework和Lambda表达式,所以我在获取某些数据时遇到了问题。通过导航属性获取数据的Lambda表达式,LINQToEntities

让我解释一下我的情况:

我有4个表的数据库,如下所示:

Database diagram

当我生成数据库在Visual Studio(2010)模型的结果是这样的:

Model in Visual Studio

我搜索了一些资料和证明,因为该表t_us er_role只有它的两个父表中的id,它会在模型​​中被抽象出来,而你必须改用导航属性。

我有一些问题得到了一个给定的系统上的用户的角色信息(作为下一个功能一样)

public t_role GetRoleForUser(string userId, string sysId) 
    { 
     entities = new secfinEntities(); //context from the model 

     t_role userRole = entities.t_role.Where(r => r.t_user.Any(u => u.uid == userId) & r.sys_id == sysId).First(); 

     return userRole; 
    } 

现在我要实现一个简单的搜索功能,将查找包含所提供的用户字符串,并返回给定系统上的用户ID和名称(uid,user_name)及其角色的信息(role_id,role_name),所以基本上我想将下一个SQL查询转换为Lambda表达式(保存在请注意,在模型中,表t_user_role已被抽象化)

SELECT U.uid, U.user_name, R.role_id, R.role_name 
FROM t_user U 
    INNER JOIN t_user_role UR ON U.uid = UR.uid 
    INNER JOIN t_role R ON UR.role_id = R.role_id 
WHERE R.sys_id = @p0 -- first parameter 
    AND U.user_name LIKE '%' + @p1 + '%' -- second parameter 

另外,我想的是,结果存储在我定义为一个类型的列表如下:

public class UserRole 
{ 
    public string UserId { get; set; } 
    public string UserName { get; set; } 
    public string RoleId { get; set; } 
    public string RoleName { get; set; } 

    public UserRole(string uid, string uname, string rid, string rname) 
    { 
     UserId = uid; 
     UserName = uname; 
     RoleId = rid; 
     RoleName = rname; 
    } 
} 

所以解释我做了什么什么,我试图做的第一个问题是后:如何做到这一点?第二:同样可以通过详细形式而不是Lambda表达式来完成吗?如果是的话,怎么样?

非常感谢您的时间。

+0

+1为准确提供我们需要的信息来帮助你 – Smudge202

回答

4

这件T-SQL:

SELECT U.uid, U.user_name, R.role_id, R.role_name 
FROM t_user U 
    INNER JOIN t_user_role UR ON U.uid = UR.uid 
    INNER JOIN t_role R ON UR.role_id = R.role_id 
WHERE R.sys_id = @p0 -- first parameter 
    AND U.user_name LIKE '%' + @p1 + '%' -- second parameter 

给你的模型转换为这个详细的语法(包括使用新型号的要求):我知道你没有问

var results = (from u in entities.t_user 
       from r in u.t_role 
       where r.sys_id == sysIdVariable && u.user_name.Contains(userNameVariable) 
       select new UserRole(u.uid, u.user_name, r.role_id, r.role_name)) 

它,但一个lambda版本可能看起来像:

var results = entities.t_user.Join(entities.t_role, 
            x => x.t_role_id, 
            x => x.role_id, 
            (u, r) => new UserRole(u.uid, 
                 u.user_name, 
                 r.role_id, 
                 r.role_name)) 
+0

好吧现在我感到惭愧,因为它非常简单,我最初认为只能用lambda表达式来完成......虽然这是我第一次看到2个这样的起源,那么究竟做了什么? –

+1

它是(在此示例中)在关系的导航属性存在时进行连接的简写。另一种办法是(请原谅代码在评论框中...)'从u中的entities.t_user加入r在entities.t_role上u.t_role_id == r.role_id其中....'你也可以将它用于加入_unrelated_实体,因为你可以指定不同的密钥加入他们等等。不要羞愧,虽然,好消息是你的问题是我已经在网站上看到的最好的阅读整个星期!:-) – Smudge202

+0

嗯,我花了我的甜蜜时间,以确保我包括每一个细节,因为我不想拉长我的头发比需要更长。并感谢您的解释,我将铭记未来:) –