我相信这应该是一个微不足道的问题,但我没有找到任何相关的答案。
我正在处理一个 MVC 5 项目(由具有标识的默认 VS 模板创建)。
我有一个帖子模型。只有授权的"用户"("用户"是创建项目时 EF 模板提供的默认 ApplicationUser 类)才能创建帖子。
我需要以这种方式扩展帖子和用户模型:
- 每个帖子都会有用户(创建它的人)
- 每个用户都将拥有由他创建的所有帖子。
换句话说,我需要 Post 和用户之间的一对多关系。(我的目标是只有Post的所有者才能编辑它。此外,每个"用户"都可以获得他的帖子列表)
我将EntityFramework 6.1.2与Identity 2.0一起使用(或1.0..不确定如何检查?
问题:
我有 2 个指向两个不同数据库表的 dbContext 类:
1) ApplicationDbContext - 创建项目时由 EF 提供的默认 DbContext,并指向 AspNetUsers 表。
2) MrSaleDB - 指向 Posts db-table 的 DbContext(以及我模型中的其他表,如 Gallery 等)
那么我应该如何扩展 Post 和用户类呢? 如何将当前用户身份与保存在扩展 Post 类中的用户进行比较(在用户编辑帖子时在 PostController 中)?
我尝试的所有方法都没有奏效)-;
这是我项目中的一些代码,谢谢:
模型:
namespace MrSaleBeta01.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
**public class ApplicationUser : IdentityUser**
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
//ADDED:
public ApplicationUser ()
{
Posts = new List<Post>();
}
public ICollection Posts { get; set; }
}
**public class Post**
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
public virtual Gallery Gallery { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
// Navigation property:
public virtual Category Category { get; set; }
//ADDED:
public virtual ApplicationUser PublishedBy { get; set; }
}
}
数据库上下文:
namespace MrSaleBeta01.Models
{
/*
* First (default) DbContext, points to users tables:
*/
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
...
}
/*
* Second DbContext, points to my models tables:
*/
public class MrSaleDB : DbContext
{
public MrSaleDB() : base("name=MrSaleDB")
{
}
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<AreaCode> AreaCodes { get; set; }
public DbSet<Gallery> Galleries { get; set; }
...
}
}
帖子控制器:
// POST: Posts/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult Edit(Post post)
{
try
{
if (ModelState.IsValid)
{
...
...
...
//General: save post:
db.Posts.Add(post);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DbEntityValidationException ex)
{
}
}
我认为将此应用程序分布在 2 个 DbContext 中不是一个好主意。
看看这里发布的这篇类似的文章:-
ASP.NET 身份数据库上下文混淆
所以我想根据我在这里得到的出色帮助来回答我自己的问题(stackoverflow 是一个救命稻草。
1)我遵循@ Steve Greene和Derek的建议,没有2个dbcontext,而是将它们合并为一个继承自IdentityContext
的数据库上下文,步骤如下:
1A) 删除任何旧的迁移和数据库
1B)在Web.config
文件中,在connectionStrings
元素下:删除旧连接字符串的2行,并添加新的连接字符串,如下所示:
<connectionStrings>
<add name="SaleConn" connectionString="Data Source=(localdb)v11.0; Initial Catalog=SaleConn; Integrated Security=True; MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
</connectionStrings>
1C) 将 2 个数据库上下文合并为一个类,如下所示:
namespace MrSaleBeta01.Models
{
public class MrSaleDB : IdentityDbContext<ApplicationUser>
{
public MrSaleDB()
: base("SaleConn", throwIfV1Schema: false)
{
}
...
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<AreaCode> AreaCodes { get; set; }
public DbSet<Gallery> Galleries { get; set; }
...
}
}
2) 通过将此属性添加到 ApplicationUser 类来建立一对多关系:
public virtual ICollection<Post> Posts { get; set; }
以及通过向我的模型类 (Post) 添加以下属性:
[ForeignKey("ApplicationUser")]
public string ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
3) 通过写入 PM 控制台为项目启用迁移:
>Enable-Migrations
>add-migration init
>update-database
4) 在 Post 控制器中添加using Microsoft.AspNet.Identity;
,以便您在下一步中获取用户 ID。更多信息..
5) 更新 Post 控制器的 Create 方法,用于将用户 ID 保存到新 POST:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
public ActionResult Create( Post post)
{
try
{
if (ModelState.IsValid)
{
post.ApplicationUserId = User.Identity.GetUserId();
...
...
...
}
}
}
6) 更新 Post 控制器的 Edit 方法,检查当前用户是否为已编辑帖子的所有者:
[Authorize]
public ActionResult Edit(int? id)
{
try
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Post post = db.Posts.Find(id);
if (post == null)
{
return HttpNotFound();
}
if( !User.IsInRole("Admin") && (post.ApplicationUserId != User.Identity.GetUserId()) )
{
return RedirectToAction("Index");
}
....
}
}
}
就是这样。再次感谢在座的各位。你帮了我这么多(-;