2015-10-14 96 views
0

我正在构建一个用于学习目的的Web应用程序,它将是一个多用户应用程序。每个用户将拥有他们的数据。我不是100%确定如何实现这一点。我应该让Model1包含一个int UserId {get; set;}属性来保存用户GUID,还是应该是IdentityUser类型?然后在我的控制器中,我是否总是考虑当前登录的用户ID以查询我的问题?我应该能够从会话中获取userId?多用户应用程序

+1

似乎是一个很好的理由来使用'Asp.Net Identity' – Milen

回答

2

由于某些原因,用户对象似乎被人吓倒,但它与任何其他类型的关系没有区别。是的,如果一个特定的实体由用户“拥有”,那么应该有一个用户实体的外键。

我假设您已经使用ASP.NET身份,因为您提到了IdentityUser,但您似乎对Entity Framework如何与关系一起工作感到困惑。从技术上讲,下面的两个属性将会对生成的表相同的净效应(例如一个名为User_Id柱:

public string User_Id { get; set; } 

OR

public virtual ApplicationUser User { get; set; } 

在第二行中,实体框架看到你因为它需要创建一个隐式外键来跟踪这个关系,它不是你的实体的一部分,而是它在数据库表上,因为实体框架显然不能存储整个用户对象位于数据库级别的单个列中,您也不想要。

这就是说,你应该对关系使用的代码实际上应该是这样的:

[ForeignKey("User")] 
public string UserId { get; set; } 
public virtual ApplicationUser User { get; set; } 

这做了两两件事:

  1. 你得到一个导航属性User,可以让你直接访问通过这个实体传递给用户对象,同时通知实体框架在这里需要跟踪的实体之间存在关系。

  2. 您有一个明确的外键属性UserId,它允许您在需要时真正获得外键。如果您希望能够执行诸如从选择列表中选择相关项目的操作,那么这通常是必需的,因为选择列表只能发布像int或字符串这样的基本类型。如果你没有这个属性,这将是更难以实现这种情况。

技术上的ForeignKey属性没有严格要求,因为实体框架将拿起UserIdUser按照惯例外键。不过,我认为最好明确一下你期望的情况,并且在约定可能不恰当的情况下,使用ForeignKey的习惯将确保事情仍然按照他们应该的方式工作。

最后,关于授权,是的,你会过滤用户的实体,以便每个用户只看到他们应该看到什么。例如:

var widgets = db.Widgets.Where(m => m.UserId == User.Identity.GetUserId()); 

或者,当你正在展示或允许用户编辑单个项目的情况:

var widget = db.Widgets.SingleOrDefault(m => m.Id == widgetId && m.UserId == User.Identity.GetUserId()); 
if (widget == null) 
{ 
    return new HttpNotFoundResult(); 
} 

就这样,用户甚至没有可视性什么其他“小部件”可能在应用程序中。如果不是他们的,他们会得到一个404,就好像事件不存在一样。

+0

那么我的创建操作呢?我是否设置了UserId和User属性? UserId没有问题,但设置用户属性呢? – Chris

+0

其实你可以设置其中一个。这主要取决于你拥有的东西。如果你有一个id,但没有用户实例,那么从数据库中查找用户只是为了设置另一个实体的属性是毫无意义的。只需设置ID,实体框架就可以解决问题。用户实例反之亦然。虽然,你仍然可以通过'user.Id'设置id,或许你会发现直接设置用户属性会更容易。无论哪种方式,Entity Framework都会将其整理出来。 –

0

试着想想所有的情况。你认为有共享登录的可能性吗?需要访问而无需登录或多次登录的用户也可能导致问题。在大多数情况下使用UserId是一个很好的解决方案,但要确保知道谁在使用它以及如何使用它。