我有一个问题,涉及基于登录用户在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并将其添加到表中。
答案 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;
然后我建议阅读这篇关于实现通用存储库的文章:
如果你想要的东西真的很简单你只需要添加到你的界面方法
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)
我原来的问题可能会引起一些关于我想要达到的目标的困惑;我冒犯错误的方式去做我想做的事情是我的错。经过大量的研究和学习,我发现我正在寻找的是一种多租户数据架构方法。