我目前有一个ASP.NET MVC4应用程序,我正在尝试为用户帐户设置SimpleMembership。到目前为止,我自动使用EF代码首次迁移进行数据库设置,并使用它在我的数据库中生成SimpleMembership表。
我想设置它,以便当前登录的用户与我创建的特定实体之间存在关系。我有两种不同类型的用户:学生和老师。这两个都来自基础“用户”类。
例如:当学生登录时,他/她将可以访问诸如他们的帐户之类的内容以及存储在与EF创建的“UserProfile”表不同的单独学生表中的其他数据。
我已经做了一些实现这个的研究,我相信我需要使用“UserId”创建一个链接作为用户的外键属性。 但是,接下来我需要采取哪些措施来实际将信息存储到不同的表中?
通过UserId键将SimpleMembership表和Student表中的数据捆绑在一起的最佳方法是什么?
以下是我的用户类,我认为这是建立两者之间关系的正确方法。
用户
public class User
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[Display(Name = "First Name")]
[Required(ErrorMessage = "First name is required.")]
[MaxLength(50)]
public virtual string FirstName { get; set; }
[Display(Name = "Last Name")]
[Required(ErrorMessage = "Last name is required.")]
[MaxLength(50)]
public virtual string LastName { get; set; }
}
学生
public class Student : User
{
public virtual ICollection<Account> Accounts { get; set; }
}
教师
public class Teacher : User
{
public virtual ICollection<Student> Students { get; set; }
public virtual ICollection<Classroom> Classrooms { get; set; }
}
答案 0 :(得分:1)
您可以生成从EntityTypeConfiguration继承的配置类,其中T是您的模型类(在您的案例中为Account,Student或Classroom)。使用流畅的API,您可以创建多对多关系,例如许多学生可能拥有多个帐户;然后,Student_x_Account的联结表可以表示STUDENT_ID与ACCOUNT_ID的关系。
答案 1 :(得分:1)
由于在单个应用程序中将SimpleMembershipProvider集成到单个DbContext中时存在关于问题的评论,我将通过创建两个单独的项目来实现使用EF的松散耦合ORM方法来解决此问题,其中一个是初始化数据库的类库。包含4个表加上UserProfile表和App项目本身。如果您在类库中遇到SMP问题,请使用vs2012创建一个空的MVC4 Web应用程序。
这最终创建了两个DbContext,您必须在DAL(WebApi,Repo,IoC等)中使用一些架构模式,而这些架构模式又可以是它自己的可重用性类库。只需确保使用UserId FK在两个应用程序/项目中的数据模型之间提供参照完整性。
<强> 1。创建两个项目;班级图书馆&amp; Web App MVC4
SMPIdentity项目(类库)
应用项目(网络应用)
2.SMPIdentity类库项目
您必须使用SimpleMembershipProvider(4.0)的控制台管理器安装这些nuget软件包才能工作:
PM> Install-Package Microsoft.AspNet.WebPages.OAuth
PM> Install-Package EntityFramework -Version 5.0.0
PM> Install-Package Microsoft.AspNet.Mvc -Version 4.0.30506
PM> Install-Package WebMatrix.WebData
3. SMPIdentity类库中的启用迁移
PM> Enable-Migrations
4.在SMPIdentity项目中添加.config文件:
<connectionStrings>
<add name="SMPConnection" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=SMP;Integrated Security=True;MultipleActiveResultSets=False" />
</connectionStrings>
<system.web>
<roleManager enabled="true" defaultProvider="SimpleRoleProvider">
<providers>
<clear />
<add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" />
</providers>
</roleManager>
<membership defaultProvider="SimpleMembershipProvider">
<providers>
<clear />
<add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
</providers>
</membership>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages" />
</namespaces>
</pages>
</system.web>
6.如果您希望向UserProfile模型添加其他属性,请创建一个空的DbContext类(SMPEntities.cs
)来存储SimpleMembershipProvider表和UserProfile表。如果不是留空
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace SMPIdentityMVC4
{
public class SMPContext : DbContext
{
public SMPContext()
: base("name=SMPConnection")
{
}
//add DbSet<UserProfile> Users if you want custom properties
//dbo.UserProfile will only have int UserId & string UserName
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
}
//Create if you want custom properties
[Table("UserProfile")]
public class UserProfile
{
//...ctors here
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[ScaffoldColumn(false), Required]
public string ImageUrl { get; set; }
[DisplayFormat(DataFormatString = "{0}")] //{0:d} or {0:D}
[DataType(DataType.DateTime), ScaffoldColumn(false)]
public DateTime DateJoined { get; set; }
}
}
6.从SMPIdentity类库中的CF迁移创建数据库:
PM> Add-migration SMPInitial
7.在迁移文件夹中编辑Configuration.cs
,并根据需要添加System.Web
对项目的引用:
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Web.Security;
using WebMatrix.WebData;
internal sealed class Configuration : DbMigrationsConfiguration<SMPContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(DomainContext context)
{
WebSecurity.InitializeDatabaseConnection(
"SMPConnection",
"UserProfile",
"UserId",
"UserName", autoCreateTables: true);
if (!WebSecurity.UserExists("yardpenalty"))
WebSecurity.CreateUserAndAccount(
"yardpenalty",
"password",
new
{
Email = "yardpenalty@email.com",
ImageUrl = "/Content/Avatars/yardpenalty.jpg",
DateJoined = DateTime.Now,
},
false);
if (!Roles.RoleExists("Administrator"))
Roles.CreateRole("Administrator");
if (!Roles.RoleExists("Blogger"))
Roles.CreateRole("Blogger");
}
<强> 8。在SMP数据库中初始化和填充表
PM> Update-database
<强> 9。创建实际Web应用程序并执行以下操作:
将参考或整个SMPIdentity项目添加到实际的MVC4 Web App
为SMP添加connectionString,因此有两个connectionStrings; SMPConnection&amp; DefaultConnection
为两个DbContext选择建筑模式,你就完成了!您可以在SMP项目完好无损的情况下在Web应用上使用代码首次迁移
控制器中的简化示例代码(依赖注入?):
public class studentController : Controller
{
private readonly SimpleMembershipRepository _accounts = null;
private readonly StudentRepository _students = null;
public StudentController(IRepository students, IRepository account)
{
_accounts = accounts;
_students = students;
}
}
如果您愿意,现在您有一个帐户数据库,其中包含整个域的SimpleMembershipProvider!创建WebApi控制器以访问Simple Membership Provider数据库以便于访问。