【问题标题】:Lambda expressions to obtain data through navigation properties, LINQToEntitiesLambda表达式通过导航属性获取数据,LINQToEntities
【发布时间】:2013-06-27 01:21:03
【问题描述】:

由于我刚刚开始使用 LINQToEntities、实体框架和 Lambda 表达式,因此在获取一些数据时遇到了问题。

让我解释一下我的情况:

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

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

我搜索了一些信息,结果发现由于表 t_user_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)以及他们在给定系统(系统信息我事先有),所以基本上我想将下一个 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 表达式来完成吗?如果是,怎么做?

非常感谢您抽出宝贵时间。

【问题讨论】:

  • +1 提供我们需要的准确信息来帮助您

标签: c# linq lambda


【解决方案1】:

这个 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))

【讨论】:

  • 好吧,现在我感到很惭愧,因为它是如此简单,我最初认为它只能通过 lambda 表达式来完成......虽然这是我第一次看到这样的 2 个 froms,但这是什么那到底是什么?
  • 这是(在此示例中)当关系存在导航属性时进行连接的简写。另一种方法是(请原谅评论框中的代码...)from u in entities.t_user join r in entities.t_role on u.t_role_id == r.role_id where.... 您也可以使用它来加入 unrelated 实体,因为您可以指定不同的键来加入它们等等。不要虽然感到羞耻,但好消息是你的问题是我整个星期在网站上看到的最好的读物! :-)
  • 好吧,我度过了美好的时光,确保我包含了所有可能的细节,因为我不想把头发拉得比需要的长。感谢您的解释,我会牢记这一点:)
猜你喜欢
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多