Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用外键将SimpleMembership用户配置文件链接到扩展配置文件?_C#_Asp.net Mvc 4_Ef Code First_Entity Framework 5_Simplemembership - Fatal编程技术网

C# 如何使用外键将SimpleMembership用户配置文件链接到扩展配置文件?

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与即将创建的播放器相同。当我按原样尝试代码时,没有响应,也没有向数据库添加或保存任何内容 团队和球员一对多关系

我已经没有办法让这段代码按照我想要的方式工作了。我有3种型号,如下所述

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);
    }
}