根据当前登录的用户显示特定数据

时间:2013-10-13 22:30:47

标签: sql-server entity-framework asp.net-mvc-4

我有一个问题,涉及基于登录用户在SQL数据库(实体框架)中返回数据行的后勤工作;我主要专注于桌面C#应用程序,并且在切换到ASP.NET MVC 4时,我在解决这个问题时遇到了一些困难(我已经搜索过了,没有一个答案似乎提供了什么我正在寻找):

我想使用内置于ASP.NET(MVC4)的授权,并允许用户使用表单发布有关其网站的数据(网站类别,网址,年龄等),并让表单存储数据(使用实体框架)到数据库(称为PrimaryDomainsDb),该数据库与UserProfile表中的Id相关联。

当用户单击按钮以显示其域列表时,如何使应用程序拉出其域列表(相关的数据行)而忽略其他用户行?

同样,我主要是寻找物流和概念(例如使用外键)和伪代码,而不是实际上给我提供一堆代码。

如果有人有任何最佳实践想法(即将UserProfile链接到PrimaryDomainDb 以这种方式,并使用EF调用与其ID 相匹配的行以返回行到视图),非常感谢。

一些示例代码:

我目前首先设置我的PrimaryDomain代码(这里没有指定最小/最大长度的装饰器等):

public class PrimaryDomain
{
    public virtual int Id { get; set; }
    public virtual string SiteName { get; set; }
    public virtual string SiteURL { get; set; }
    public virtual SitePlatforms SitePlatform { get; set; }
    public virtual decimal? SiteDA { get; set; }
    public virtual decimal? SitePA { get; set; }
    public virtual string SiteAge { get; set; }
    public virtual DateTime? LastStatusUpdate { get; set; }
    public virtual string SiteIP { get; set; }
}

我有一个与ASP.NET WebSecurity提供的用户类不同的用户类,如下所示:(另外,我知道“密码”不应该是字符串格式,这只是初始设置 - 目的 - 密码应该完全删除并由WebSecurity处理,我认为。)

public class User
{
    public virtual int Id { get; set; }
    public virtual string Username { get; set; }
    public virtual string Password { get; set; }
    public virtual string Email { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string MozAccessID { get; set; }
    public virtual string MozKey { get; set; }
    public virtual decimal AccuountBalance { get; set; }

    public virtual PrivateProxy PrivateProxies { get; set; }
    public virtual PrimaryDomain PrimaryDomains { get; set; }

}

在为Views提取数据时,我使用直接注入通过存储库运行所有内容:

public interface IUserDataSource
{
    IQueryable<User> Users { get; }
    IQueryable<PrimaryDomain> PrimaryDomains { get; }

    void Save();
}

这是我的UserDb类,只要代码调用IUserDataSource(通过直接注入)就会输入:

public class UserDb : DbContext, IUserDataSource
{
    public UserDb()
    : base("DefaultConnection")
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<PrimaryDomain> PrimaryDomains { get; set; }



    IQueryable<User> IUserDataSource.Users
    {
        get { return Users; }
    }

    IQueryable<PrimaryDomain> IUserDataSource.PrimaryDomains
    {
        get { return PrimaryDomains; }
    }

    void IUserDataSource.Save()
    {
        SaveChanges();
    }
}

例如,我将如何将PrimaryDomains模型传递给View:

public class NetworkController : Controller
{
    //
    // GET: /Network/
    private IUserDataSource _db;

    public NetworkController(IUserDataSource db)
    {
        _db = db;
    }

    public ActionResult ListDomains()
    {
        var allDomains = _db.PrimaryDomains;
        return View(allDomains);
    }
}

但我没有从数据源中提取整个PrimaryDomains列表,而是想添加一种方法来引用当前登录的用户ID,以使应用程序仅显示该特定用户的域,而不是所有域,以及何时通过表单添加新域以引用用户ID并将其添加到表中。

2 个答案:

答案 0 :(得分:0)

这可能就是你要找的东西。如果我理解正确,您希望使用WebSecurity登录或注册用户,但您希望使用实体框架来存储一些特定于用户的数据。下面的代码将WebSecurity表与使用EntityFramework创建的数据库CodeFirst连接起来。

您可以在下面创建课程(来自教程)。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    if(!WebSecurity.Initialized)
                        WebSecurity.InitializeDatabaseConnection("ConnectionString", "DbUsers", "UserId", "Email", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
                }
            }
        }
    }

它创建了用于注册和记录用户的必要表。神奇的是第二,第三和第四参数。它可以分别是您可以通过EntityFramework创建的数据库中的table,userId列和userName列。 WebSecurity使用该表以及其他自生成的表来管理您的用户并让他们注册,登录等。

然后在代码中首先创建表

public class DbUser
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    [MaxLength(40)]
    public string Email { get; set; }
    [MinLength(3)]
    [MaxLength(30)]
    [Required]
    public string FirstName { get; set; }
    [MinLength(3)]
    [MaxLength(50)]
    [Required]
    public string LastName { get; set; }
}

然后您可以简单地从控制器查询数据。在下面的示例中,我使用WebSecurity成员资格存储的UserId从数据库中检索帐户信息。

public ActionResult AccountInfo()
        {
            if (FormsAuthentication.CookiesSupported == true && Request.Cookies[FormsAuthentication.FormsCookieName] != null)
            {
                var userId = WebSecurity.CurrentUserId;
                var userInfo = context.Users.FirstOrDefault(x => x.UserId == userId);
                userInfo.Password = "";
                return View(userInfo);
            }
            else
            {
                ModelState.AddModelError("", "Wystąpił bląd autoryzacji, zaloguj się jeszcze raz.");
                return RedirectToAction("Login", "Account");
            }
        }

修改

关于您理解的编辑问题,除了您需要如上所述将WebSecurity与EF集成之外(我也忘了提到在创建如上所述的InitializeSimpleMmebershipAttribute类后需要使用该属性修饰控制器),您也遇到了问题实现通用存储库。如果该行存在问题:

var allDomains = _db.PrimaryDomains;

然后我建议阅读这篇关于实现通用存储库的文章:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

如果你想要的东西真的很简单你只需要添加到你的界面方法

GetDomainByUserId(int userId)

只需实现那样的界面:

public class UserDb : DbContext, IUserDataSource
{
    public UserDb()
    : base("DefaultConnection")
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<PrimaryDomain> PrimaryDomains { get; set; }



    IQueryable<User> IUserDataSource.Users
    {
        get { return Users; }
    }

    IQueryable<PrimaryDomain> IUserDataSource.PrimaryDomains
    {
        get { return PrimaryDomains; }
    }

    IQueryable<PrimaryDomain> GetDomainByUserId(int userId)
    {
        return PrimaryDomains.Where(x => x.Id == userId).ToQueryable();
    }

    void IUserDataSource.Save()
    {
        SaveChanges();
    }
}

但这是非常糟糕的做法,我强烈建议您阅读该文章。

答案 1 :(得分:0)

我原来的问题可能会引起一些关于我想要达到的目标的困惑;我冒犯错误的方式去做我想做的事情是我的错。经过大量的研究和学习,我发现我正在寻找的是一种多租户数据架构方法。