【问题标题】:How to work with Entity Framework and ASP.NET membership tables?如何使用实体框架和 ASP.NET 成员表?
【发布时间】:2011-02-21 20:12:18
【问题描述】:

我正在为当前不断变化的 Silverlight 应用程序创建实体模型。我的一般工作流程是根据需要添加和删除位,然后在我工作时从实体模型生成数据库。

我正在尝试将 ASP.NET 用户/成员表合并到实体模型中,但遇到了一些烦人的问题。我正在尝试将我自己的 Courses 表与 aspnet_Users 表以多对多关系关联起来。这根本不需要修改 aspnet_Users 表,只需要修改 Courses 上的外键。但是,当我尝试从模型构建数据库时,我从 EF 收到错误,因为它试图删除 aspnet_Users 并重新创建它,但由于来自其他 aspnet_* 表的外键关系而失败。

我是否以完全错误的方式处理这件事?我是否应该使用某种成员资格提供程序模型来挂钩 ASP.NET 成员资格/角色等?有什么方法可以让我做我需要做的事情,但仍然利用 ASP.NET 团队所做的所有工作,并为自己省去创建自己的角色/成员资格/个人资料系统的麻烦?

【问题讨论】:

  • 有非常好的 API 用于处理 ASP.NET 数据库表中包含的数据。您应该使用它们,因为它们 1) 将您与 ASP.NET 团队可能决定对其架构进行的任何更改隔离开来;2) 如果您切换到不同的成员资格提供程序,则允许您的应用程序在不更改任何代码的情况下工作。告诉我们您想要完成什么,我们可以指出要使用的特定 API。
  • 谢谢罗伯特,如果我找不到合适的解决方案,我会尽快更新我的问题并提供更多详细信息。有趣的是,我刚刚发现这篇文章blogs.teamb.com/craigstuntz/2010/03/05/38558 基本上说我想错了——我根本不应该依赖 ASP.NET 成员表。在其他意见中仍然很有趣。
  • 我从来都不喜欢大多数 MS 提供程序模型背后的完整实现。除非您的使用场景适合他们实施的狭窄(并且非常基本)设计,否则您将无法自定义它,这最终会比从头开始自己滚动更痛苦......

标签: entity-framework-4 asp.net-membership


【解决方案1】:

(我来这里是因为我在对没有人回答我的问题感到沮丧之后正在阅读关于 SO 的帖子,而且我想我会把我的 2c 价值投入这个仍在等待答案的人身上。 .)

在 EF V5 之前,我使用角色和成员资格配置文件提供程序解决了这个问题。

在您的 web.config 文件中(保存与您的 asp.net 成员数据的数据库连接的文件,您可以定义如下内容:

<profile enabled="true" defaultProvider="MyProfileProvider">

  <providers>
    <clear />
    <add name="MyProfileProvider"
         connectionStringName="vbox01"
         type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </providers>

  <properties>
    <add name="FirstName" type="System.String" />
    <add name="LastName" type="System.String" />
    <add name="BirthDay" type="System.DateTime" />
    <add name="CustomBackColour" type="System.String" />
    <add name="CustomLinkColour" type="System.String" />
    <add name="CustomLinkHoverColour" type="System.String" />
    <add name="ProfilePhoto" type="System.String" />
    <add name="Modules" type="System.Collections.Generic.List`1[System.String]" serializeAs="Binary"/>
    <add name="SideModules" type="System.Collections.Generic.List`1[System.String]" serializeAs="Binary"/>
    <add name="DefaultPageName" type="System.String" />
    <add name="DefaultModule" type="System.String" />
    <add name="PersonalPage" type="System.Boolean" />
  </properties>
</profile>

添加后,您可以通过以下方式支持在您的网络应用中访问它:

using System;
using System.Collections.Generic;
using System.Web.Profile;

namespace intranet.web.Classes
{
  public class ProfileCommon : ProfileBase
  {
    [SettingsAllowAnonymous(false)]
    public string FirstName
    {
      get { return base["FirstName"] as string; }
      set { base["FirstName"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string LastName
    {
      get { return base["LastName"] as string; }
      set { base["LastName"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public DateTime BirthDay
    {
      get { return (DateTime)base["BirthDay"]; }
      set { base["BirthDay"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string CustomBackColour
    {
      get { return base["CustomBackColour"] as string; }
      set { base["CustomBackColour"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string CustomLinkColour
    {
      get { return base["CustomLinkColour"] as string; }
      set { base["CustomLinkColour"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string CustomLinkHoverColour
    {
      get { return base["CustomLinkHoverColour"] as string; }
      set { base["CustomLinkHoverColour"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string ProfilePhoto
    {
      get { return base["ProfilePhoto"] as string; }
      set { base["ProfilePhoto"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public List<string> Modules
    {
      get { return (List<string>)base["Modules"]; }
      set { base["Modules"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public List<string> SideModules
    {
      get { return (List<string>)base["SideModules"]; }
      set { base["SideModules"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string DefaultPageName
    {
      get { return base["DefaultPageName"] as string; }
      set { base["DefaultPageName"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public string DefaultModule
    {
      get { return base["DefaultModule"] as string; }
      set { base["DefaultModule"] = value; }
    }

    [SettingsAllowAnonymous(false)]
    public bool PersonalPage
    {
      get { return (bool)base["PersonalPage"]; }
      set { base["PersonalPage"] = value; }
    }

  }
}

它建立在由 System.Web.Profile 在 ASP.NET 运行时公开的“ProfileBase”类之上。

我也为自己构建了一些助手,类似于以下:

public static MemberData GetMemberDataFor(string userName)
{
  MemberData result = new MemberData();

  MembershipUser user = Membership.GetUser(userName);
  if(user != null)
  {
    ProfileCommon pc = new ProfileCommon();
    pc.Initialize(userName, true);

    result.UserName = user.UserName;
    result.FirstName = pc.FirstName;
    result.LastName = pc.LastName;
    result.Birthday = pc.BirthDay;
    result.BackGroundColour = pc.CustomBackColour;
    result.LinkColour = pc.CustomLinkColour;
    result.HoverColour = pc.CustomLinkHoverColour;
    result.ProfilePhoto = pc.ProfilePhoto;
    result.DefaultPage = pc.DefaultPageName;
    result.HasPersonalPage = pc.PersonalPage;
    result.Modules = pc.Modules;
    result.SideModules = pc.SideModules;
    result.DefaultModule = pc.DefaultModule;
    result.DateRegistered = user.CreationDate;
    result.MemberId = (Guid?) user.ProviderUserKey;

  }
  else
  {
    result = null;
  }

  return result;
}

另一种方式(虽然我猜你可以在任何其他无数事物上使用 automapper,stucturemap,出于我的上述目的,它的表亲足以满足我正在从事的小项目,让我得到从我的视图模型来看,事情也来来回回。

在您的情况下,您最喜欢将此类和配置信息放在某种服务 API 后面,然后将 Json 对象提供给您的 silverlight 应用程序。

然而,所有这一切的巧妙之处在于它不需要更改数据库架构。角色和成员资格系统已经有列来保存序列化/反序列化数据,因此您可以随时从类和 web.config 文件中添加/删除条目,系统将按原样使用它们,任何删除我都可以拉回一次但永远不会再次保存,新的可能在第一次使用时不存在,但会在您第一次保存对象时保存。

然而,这两种极端情况可以通过一些创造性的错误处理相对容易地处理。

我知道这与拥有单独的表不同,但它是一个很好的解决方法,而且它也适用于旧版本的 EF。

但是,如果您使用的是 EF5+,那么您应该只检查实体迁移的东西,坦率地说,它只是摇摆不定。设置好后,数据库更新就很简单了,只需在包管理器控制台窗口中添加一些新命令即可。

我知道这为时已晚 2 年,但希望它以某种晦涩难懂的方式有所帮助。

肖蒂

【讨论】:

  • 哇哇!这个问题已经有几年了,所以显然我不再面临同样的问题,但我非常感谢你的回答。干得好!
  • 至于 EF 5+,是的,我今天使用的是代码优先迁移,它们很棒。
  • 很高兴为您提供帮助...我将很快发布一两篇博文,讨论我昨天在 EF5 中必须解决的一个非常棘手的问题!如果您使用 SQLite 和 GIS,那么当我编写它时,它会值得一读 :-) 当它上线时,我可能会在我的推特 @shawty_ds 上宣布它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多