【问题标题】:Linq To Entities - Get User Info With All RolesLinq To Entities - 获取所有角色的用户信息
【发布时间】:2012-09-19 03:03:27
【问题描述】:

我是 Linq 的新手,正在使用新的 MVC 站点对其进行测试。我仍在研究语法和功能,但遇到了一个我无法解决的问题。任何帮助将不胜感激。

情况:

1 - 我有一个 SQL 数据库设置来使用默认的 ASPNET 成员资格提供程序。保留标准命名约定(aspnet_Users、aspnet_Roles、aspnet_UsersInRole 等)

2 - 我添加了一个名为 Users 的表,它提供了扩展的用户信息。 FK 是 aspnet_User UserId(一对一)。

3 - 我添加了一个名为“客户”的表,它提供客户(订购)信息。 FK 是来自 Users 表的 UserId(一对一)。

4 - 我添加了一个名为 CustomerAddress 的表格,它提供了客户地址信息。 FK 是 Customers 表中的 CustomerId(一对多)。

5 - 我已经建立了一个模型来处理向管理员展示这些信息

问题:

1 - 我想在此演示模型中包含应用程序中所有可用角色的列表,以及用户当前是否被分配到该角色。

2 - 我想在此演示模型中包含与用户关联的所有地址的列表

3 - 我不知道如何使用 Linq 查询将此信息返回到我的演示模型中

这是我的演示模型(请注意,我目前有一个角色属性,但我无法弄清楚如何获取此信息。并且...我不确定该类型应该是什么?

namespace Lambuth.PresentationModels.ManageUsers
{
public class UserDetail
{
[Editable(false)]
[Key, ScaffoldColumn(false)]
[Display(Name="User ID")]
public Guid UserId { get; set; }

[Required]
[Editable(false)]
[StringLength(16)]
[Display(Name="User Name")]
public string UserName { get; set; }

[Editable(false)]
[ScaffoldColumn(false)]
[StringLength(16)]
[Display(Name = "Lowered User Name")]
public string LoweredUserName { get; set; }

[Required]
[Editable(false)]
[StringLength(256)]
[Display(Name = "Email")]
public string Email { get; set; }

[Editable(false)]
[ScaffoldColumn(false)]
[StringLength(256)]
[Display(Name = "Lowered Email")]
public string LoweredEmail { get; set; }

[Editable(false)]
[StringLength(16)]
[Display(Name = "Site Alias")]
public string SiteAlias { get; set; }

[Required]
[Editable(false)]
[Display(Name = "Is Approved")]
public bool IsApproved { get; set; }

[Required]
[Editable(false)]
[Display(Name = "Is Locked Out")]
public bool IsLockedOut { get; set; }

[Editable(false)]
[Display(Name = "Join Date")]
public DateTime JoinDate { get; set; }

[Editable(false)]
[Display(Name = "Full Name")]
public string FullName
{
  get
  {
    AccountInfoHelpers help = new AccountInfoHelpers();
    return help.GetFullName(this.Salutation, this.FirstName, this.LastName);
  }
  set {/*no implmentation*/}
}

[Editable(false)]
[StringLength(20)]
[Display(Name = "Salutation")]
public string Salutation { get; set; }

[Editable(false)]
[StringLength(50)]
[Display(Name = "First Name")]
public string FirstName { get; set; }

[Editable(false)]
[StringLength(50)]
[Display(Name = "Last Name")]
public string LastName { get; set; }

[Editable(false)]
[Display(Name = "Last Login Date")]
public DateTime LastLoginDate { get; set; }

[Editable(false)]
[Display(Name = "Assigned Roles")]
public virtual ICollection<UserRole> AssignedRoles { get; set; }

} }

这是我目前拥有的 Linq 查询:

using (LambuthEntities context = new LambuthEntities())
  {
    var user = (from u in context.aspnet_Users
                join p in context.aspnet_Membership on u.UserId equals p.UserId
                join ux in context.Users on u.UserId equals ux.user_id
                join c in context.Customers on ux.user_id equals c.user_id
                where (ux.user_id == userId)  //userId passed in as param

                select new UserDetail
                {
                  UserId = ux.user_id,
                  UserName = u.UserName,
                  SiteAlias = ux.site_alias,
                  Email = p.Email,
                  Salutation = c.salutation,
                  FirstName = c.first_name,
                  LastName = c.last_name,
                  LastLoginDate = p.LastLoginDate,
                  IsApproved = p.IsApproved,
                  IsLockedOut = p.IsLockedOut
                }).Single();

    return user;
  }

我在正确的轨道上吗?任何建议将不胜感激。

谢谢。

【问题讨论】:

  • 您的.Single() 应该类似于.Single(a =&gt; a.UserId == 200)。否则,您将返回包含多个用户的查询,并且对 .Single() 的调用将引发异常。
  • 嗨 Kittoes - 感谢您的回复。我添加了一个注释,表明 userId 作为参数传入。它只返回该特定 GUID 的记录。这工作正常...但我想返回与特定用户关联的所有角色和地址。
  • 就业务逻辑和 ASP.Net 成员的结合而言,这看起来不错,请参阅 stackoverflow.com/a/12450829/861716
  • 谢谢格特。但这并不能回答我的问题。我已经在我的实体模型中内置了成员资格表。这更像是一个特定的 Linq 问题:如何在 Linq 查询中获取系统角色的集合、用户是否属于该角色以及客户地址的集合。

标签: linq entity-framework-4 linq-to-entities asp.net-membership entity-relationship


【解决方案1】:

我会做一些不同的 Linq 语句。虽然 LinqToSql 可用于生成 SQL 语句并且能够看起来像 SQL 语句(如您在示例中看到的那样),但我倾向于从生成的对象的角度使用它们。

我的意思是,我不是自己处理表之间的连接,而是利用 LinqToSql 生成器已经完成的工作并使用它们的对象。业务对象已经具有链接到相关对象的属性。

这是我将如何执行您的 linq 语句:

var user = (from u in context.aspnet_Users
            where (ux.user_id == userId)  //userId passed in as param
            select new UserDetail
            {
              UserId = u.user_id,
              UserName = u.UserName,
              SiteAlias = u.User.site_alias,
              Email = u.aspnet_Membership.Email,
              Salutation = u.User.Customer.salutation,
              FirstName = u.User.Customer.first_name,
              LastName = u.User.Customer.last_name,
              LastLoginDate = u.aspnet_Membership.LastLoginDate,
              IsApproved = u.aspnet_Membership.IsApproved,
              IsLockedOut = u.aspnet_Membership.IsLockedOut,
              AssignedRoles = u.aspnet_Roles.Select(r => r.RoleName).ToList()
            }).Single();

我不确定 UserRole 类是什么样的,所以我现在只有一个字符串集合。此外,由于没有您拥有的特定 SQL 方案(您已设置的属性),我偏离了您对对象关系的描述。

此外,在处理从多个表中提取数据的 LinqToSQL 语句时,您需要确保尽可能少地调用数据库。如果你不这样做,你可以遇到SELECT n+1 problem。解决此问题的一种方法是在 LinqToSql 中使用DataLoadOptions

【讨论】:

  • 谢谢 SBurris。我知道这已经晚了很多年,但我从来没有看到你的回复。感谢您抽出宝贵的时间,我很抱歉从未看到这一点。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多