C# 如何使用外键将SimpleMembership用户配置文件链接到扩展配置文件?
我已经没有办法让这段代码按照我想要的方式工作了。我有3种型号,如下所述C# 如何使用外键将SimpleMembership用户配置文件链接到扩展配置文件?,c#,asp.net-mvc-4,ef-code-first,entity-framework-5,simplemembership,C#,Asp.net Mvc 4,Ef Code First,Entity Framework 5,Simplemembership,我已经没有办法让这段代码按照我想要的方式工作了。我有3种型号,如下所述 UserProfile和Player一对一关系 首先创建UserProfile,在注册时电子邮件确认发送到用户提供的电子邮件。一旦他们确认他们的帐户,他们将被重定向到他们的第一个登录页面,如果经过身份验证,将被重定向到“创建新玩家”页面,以提供有关他们扩展配置文件的更多信息。在创建页面上,我希望登录用户的UserId与即将创建的播放器相同。当我按原样尝试代码时,没有响应,也没有向数据库添加或保存任何内容 团队和球员一对多关系
UserProfile和Player
一对一关系
首先创建UserProfile,在注册时电子邮件确认发送到用户提供的电子邮件。一旦他们确认他们的帐户,他们将被重定向到他们的第一个登录页面,如果经过身份验证,将被重定向到“创建新玩家”页面,以提供有关他们扩展配置文件的更多信息。在创建页面上,我希望登录用户的UserId
与即将创建的播放器相同。当我按原样尝试代码时,没有响应,也没有向数据库添加或保存任何内容
团队和球员
一对多关系
不言而喻,一名球员必须属于一支球队。这使得重定向到编辑操作成为禁止操作,因为Player.TeamId!=空
UserProfile
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public virtual Player Player { get; set; }
}
团队
public class Team
{
[Key]
[HiddenInput(DisplayValue = false)]
public int TeamId { get; set; }
[Display(Name = "Full Name:")]
public string Name { get; set; }
public virtual ICollection<Player> Players { get; set; }
}
SavePlayer
public class Player
{
[Key]
[ForeignKey("UserProfile")]
[HiddenInput(DisplayValue = false)]
public int UserId { get; set; }
[Required]
[Display(Name = "Full name")]
public string FullName{ get; set; }
[Display(Name = "Team")]
public int TeamId { get; set; }
public virtual Team Team { get; set; }
public virtual UserProfile UserProfile { get; set; }
}
public void SavePlayer(Player player)
{
using (var context = new EFootballDb())
{
if (player.UserId == 0)
{
context.Players.Add(player);
}
else if (player.UserId > 0)
{
var currentPlayer = context.Players
.Single(t => t.UserId == player.UserId);
context.Entry(currentPlayer).CurrentValues.SetValues(player);
}
context.SaveChanges();
}
}
创建操作
[HttpGet]
public ActionResult Create()
{
PopulateTeamsDropDownList();
return View();
}
[HttpPost]
public ActionResult Create(Player model)
{
try
{
if (ModelState.IsValid)
{
_dataSource.SavePlayer(model);
return RedirectToAction("Detail", "Team", new { id = model.TeamId });
}
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
PopulateTeamsDropDownList(model.TeamId);
return View(model);
}
private void PopulateTeamsDropDownList(object selectedTeams = null)
{
var teamsQuery = from d in _dataSource.Teams
orderby d.Name
select d;
ViewBag.TeamID = new SelectList(teamsQuery, "TeamId", "Name", selectedTeams);
}
在
团队和玩家
之间一切正常,但我就是无法在创建时将用户配置文件和玩家
链接起来。有没有人有我应该尝试的想法或不同的方法?提前谢谢 更新:我正在添加另一种方法来实现这一点。这是一个非常复杂的方法,它可以工作,但最终你不会想要这个
这是一种痛苦。我也花了很多时间弄明白这一点。我找到的最近的在线资源是
请注意,该页上有两个错误。
1) 使用添加迁移而不是创建迁移
2) 更新UsersContext时,请确保包含DbSet的泛型类型。即
public DbSet<Membership> Membership { get; set; }
别忘了更新UsersContext。注意:您可以将UsersContext重命名为任何您喜欢的名称
public DbSet<User> Users { get; set; }
迁移的原因是它允许您在自己的上下文中控制成员资格表。我试图在不同的环境中创建它们,但没有成功。我希望这能满足您的需要。一种更简单的方法是创建一个类,其中包含用户配置文件的虚拟外键。虚拟是用于延迟加载的。我这样做的原因是,一旦我到了OAuth,工作起来就容易多了
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int UserProfileId { get; set; }
[ForeignKey("UserProfileId")]
public virtual UserProfile UserProfile { get; set; }
}
然后将UsersContext从AccountModels.cs移到自定义上下文中,如下所示
public class OAuthNoMigrateContext : DbContext
{
public OAuthNoMigrateContext()
: base("DefaultConnection")
{
}
public DbSet<User> Users { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
将此添加到应用程序启动
Database.SetInitializer(new OAuthNoMigrateInitializer());
注意:我想创建一个方法来检查用户,并从应用程序开始调用。初始化是在您第一次调用数据库时启动的,这样做
private static void ViewDb()
{
using (var context = new OAuthNoMigrateContext())
{
var user = context.Users.Where(u => u.FirstName.StartsWith("T"));
}
}
这就叫初始值设定项
public class OAuthNoMigrateInitializer : DropCreateDatabaseAlways<OAuthNoMigrateContext>
{
private readonly CustomSimpleMembershipProvider _provider = new CustomSimpleMembershipProvider();
protected override sealed void Seed(OAuthNoMigrateContext context)
{
//Initialize UserProfile
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
AddUsers(context);
}
private void AddUsers(OAuthNoMigrateContext context)
{
if (WebSecurity.UserExists("username")) return;
var user = new User
{
FirstName = "FName",
LastName = "LName"
};
_provider.CreateUser("username", "password", user);
}
}
公共类OAuthNoMigrateInitializer:DropCreateDatabaseAlways
{
私有只读CustomSimpleMembershipProvider _provider=新CustomSimpleMembershipProvider();
受保护的重写密封的无效种子(OAuthNoMigrateContext上下文)
{
//初始化用户配置文件
WebSecurity.InitializeDatabaseConnection(“DefaultConnection”、“UserProfile”、“UserId”、“UserName”,autoCreateTables:true);
添加用户(上下文);
}
私有void AddUsers(OAuthNoMigrateContext上下文)
{
if(WebSecurity.UserExists(“username”))返回;
var user=新用户
{
FirstName=“FName”,
LastName=“LName”
};
_CreateUser(“用户名”、“密码”、用户);
}
}
这对我来说并不合适。我试了好几种方法,但还没有成功。仅添加和保存UserProfile,而不添加其他内容。保存UserProfile并查看数据库结构时,UserProfile与相关表之间的关系是否正确?另外,在尝试保存相关对象时,是否会出现异常?到目前为止,我可以确定UserProfile和其他相关成员资格表已更新。我在UserProfile中没有列来保存播放器的数据,因为我正在获取UserProfile的用户ID并将其作为外键传递给播放器。我认为WebSecurity.CurrentUserId
或任何相关调用都将出现空值。我认为这与我使用的上下文有关,它与WebSecurity使用的上下文不同。不会引发异常,如果数据未保存,我确实存在异常。很抱歉,响应延迟。必须单独添加玩家数据。使用我在上面详细介绍的CustomSimpleMembershipProvider类,而不是User,您将添加播放器表数据。不要忘记注释掉或删除AccountController.cs中的[InitializeSimpleMembership],因为您已经在种子中初始化了。
Database.SetInitializer(new OAuthNoMigrateInitializer());
private static void ViewDb()
{
using (var context = new OAuthNoMigrateContext())
{
var user = context.Users.Where(u => u.FirstName.StartsWith("T"));
}
}
public class OAuthNoMigrateInitializer : DropCreateDatabaseAlways<OAuthNoMigrateContext>
{
private readonly CustomSimpleMembershipProvider _provider = new CustomSimpleMembershipProvider();
protected override sealed void Seed(OAuthNoMigrateContext context)
{
//Initialize UserProfile
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
AddUsers(context);
}
private void AddUsers(OAuthNoMigrateContext context)
{
if (WebSecurity.UserExists("username")) return;
var user = new User
{
FirstName = "FName",
LastName = "LName"
};
_provider.CreateUser("username", "password", user);
}
}