EF数据库首先向实体添加新属性

时间:2014-03-06 14:57:28

标签: c# entity-framework inheritance extend

如何扩展dll中存在的EF实体? 我希望能够创建一个引用该DLL的新项目,并且能够添加属性和相关实体,而无需更改原始dll。

dll尚未编译,因为我们处于项目的早期阶段,但我们希望保留所有内容,以便我们以后可以扩展它们。

我们可以修改数据库以添加新属性。

我们正在构建一个具有核心功能(安全性,菜单,审核)的基础(或平台)项目,我们正在将其包含在dll中,我们将其作为使用其他项目的起点。 我们的场景类似于thisthis,但我们使用的是数据库优先方法,因此这里提出的解决方案似乎并不适用。 (如果我错了请纠正我。)

如果没有dll限制,如果我们想添加一个新属性,我们只需在db中添加该列,重新生成模型,然后添加并映射该属性。但是,由于我们想让平台dll关闭,事情并不那么容易。

特别是,我们希望能够扩展用户实体,例如,添加几个varchar列,并向新实体添加关系(Marital Status)。我们还使用了预先加载,因此我们还需要使用Include来获取新属性。

以下是生成的用户实体:

public partial class User
{
    public User()
    {
        this.Auditoria = new HashSet<Auditoria>();
        this.UserPermission = new HashSet<UserPermission>();
        this.UserPositionLog = new HashSet<UserPositionLog>();
    }

    public int userId { get; set; }
    public string username { get; set; }
    public string password { get; set; }
    public Nullable<System.DateTime> lastActivityDate { get; set; }
    public Nullable<System.DateTime> lastLoginDate { get; set; }
    public Nullable<System.DateTime> lastPasswordChangedDate { get; set; }
    public System.DateTime creationDate { get; set; }
    public bool isLockedOut { get; set; }
    public Nullable<System.DateTime> lastLockedOutDate { get; set; }
    public int failedPasswordAttemptCount { get; set; }
    public Nullable<int> roleId { get; set; }
    public string email { get; set; }
    public bool active { get; set; }
    public bool admin { get; set; }
    public string name { get; set; }
    public string devicePIN { get; set; }
    public string sessionToken { get; set; }
    public string appVersionNumber { get; set; }

    public virtual ICollection<Auditoria> Auditoria { get; set; }
    public virtual Role Role { get; set; }
    public virtual ICollection<UserPermission> UserPermission { get; set; }
    public virtual ICollection<UserPositionLog> UserPositionLog { get; set; }
}

总结了这个场景。

我试过通过继承来扩展实体: 创建了一个新的测试模型,映射到与原始dll相同的db,然后我在db中添加了新属性。作为一个例子,我添加了一个属性婚姻状态,它映射到一个新实体,该实体说明用户是否已结婚,单身,离婚。我将修改后的表映射到名为“MaritalUser”的实体。手动修改类,删除重复的东西并将其设置为从旧用户继承:

public partial class MaritalUser : SDK.DAL.Model.User
{
    public Nullable<int> maritalStatusId { get; set; }

    public virtual MaritalStatus MaritalStatus { get; set; }
}

到目前为止,旧项目工作正常,新列没有问题,它们被忽略了。在新项目中,我可以获得扩展用户,如果我使用新类,我可以使用预先加载来加载MaritalStatus实体。然而,我无法加载加载角色,例如(基类的属性),因为我得到例外:A specified Include path is not valid. The EntityType 'MaritalUser' does not declare a navigation property with the name 'Role'.

通常,EF不支持在基本类型中定义的属性包含。我无法解决这个问题。

然而,我可以编辑连接字符串以包含来自两个edmx文件的资源,如下所示:

<add name="SampleEntities" connectionString="metadata=res://*/DAL.Model.BackendEntities.csdl|res://*/DAL.Model.BackendEntities.ssdl|res://*/DAL.Model.BackendEntities.msl|res://*/SampleEntities.csdl|res://*/SampleEntities.ssdl|res://*/SampleEntities.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=...;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" />

这允许新上下文重用旧上下文中的东西,我可以查询这两种类型。虽然它们在db中是相同的,但是上下文需要单独处理它们。 到目前为止,我能想到的最好的是,编辑获取用户的所有方法,并在其中获取两种类型,将它们合并到派生类中并返回。

这是我能得到的最好的吗?有更优雅的解决方案吗?

修改 为了澄清,我们要添加到实体的新属性将映射到数据库中的新列。部分类不是一个选项,因为我们需要在dll关闭后扩展。

0 个答案:

没有答案