sql-server - 如何向我的 EF4 模型添加计算列?

标签 sql-server entity-framework entity-framework-4 calculated-columns

给定 MS SQL 2008 中的“用户”表和“登录”表:

CREATE TABLE [dbo].[User_User](
    [UserID] [int] IDENTITY(1000,1) NOT NULL,
    [UserName] [varchar](63) NOT NULL,
    [UserPassword] [varchar](63) NOT NULL
)
CREATE TABLE [dbo].[Util_Login](
    [LoginID] [int] IDENTITY(1000,1) NOT NULL,
    [User_UserID] [int] NOT NULL, -- FK REFERENCES [dbo].[User_User] ([UserID])
    [LoginDate] [datetime] NOT NULL,
)

如何调整我的 User_User Entity Framework 模型对象包含一个返回 MAX(LoginDate) 的“UserLastLogin”列?

我知道我可以围绕 SQL View 创建 EF4 模型:
CREATE VIEW [v_User_User]
AS
SELECT 
        [User_User].*, 
        (
                SELECT MAX(LoginDate) 
                FROM [Util_Login] 
                WHERE User_UserID = UserID
        ) AS UserLastLogin
FROM [User_User]

但是有没有一种方法可以修改 User_User 模型以包含计算出的列?

编辑:我正在寻找一种在单个数据库查询中获取用户或 List 包括 Max(Util.LastLogin) 日期的方法。

最佳答案

很好的问题,是的,在 EF4 中有一种完美的方法可以做到这一点:

自定义属性 是一种向实体提供计算属性的方法。好消息是自定义属性不一定需要从同一实体上的其他现有属性计算,根据我们即将看到的代码,它们几乎可以从我们喜欢的任何东西计算!

以下是步骤:

首先创建一个部分类并在其上定义一个自定义属性(为简单起见,我假设 User_User 表已映射到 User 类,Util_Login 映射到 Util)

public partial class User {
    public DateTime LastLoginDate { get; set; }
}

因此,正如您在此处看到的,我们没有在模型中创建 LastLoginDate 属性(需要映射回数据存储),而是在分部类中创建了该属性,然后我们可以选择在 期间填充它对象具体化 按需 如果您不相信每个实体对象都需要提供该信息。

在您的情况下,为每个被具体化的用户预先计算 LastLoginDate 自定义属性是有用的,因为我认为这个值将被所有(或至少大部分)被具体化的实体访问。否则,您应该考虑仅在需要时而不是在对象实现期间计算属性。

为此,我们将利用 ObjectContext.ObjectMaterialized Event,它会在任何时候从查询返回数据时引发,因为 ObjectContext 正在从该数据创建实体对象。 ObjectMaterialized 事件是 Entity Framework 4 的事情。
所以我们需要做的就是创建一个事件处理程序并将其订阅到 ObjectMaterialized 事件。

放置此代码(订阅事件)的最佳位置是 OnContextCreated Method 内。该方法由上下文对象的构造函数和构造函数调用
重载是没有实现的部分方法,只是由 EF 代码生成器创建的方法签名。

好的,现在您需要为 ObjectContext 创建一个分部类。 (我假设名称是 UsersAndLoginsEntities)并将事件处理程序(我将其命名为 Context_ObjectMaterialized)订阅到 ObjectMaterialized 事件。
public partial class UsersAndLoginsEntities {
    partial void OnContextCreated() {
        this.ObjectMaterialized += Context_ObjectMaterialized;
    }
}

最后一步(真正的工作)是实现这个处理程序来为我们实际填充自定义属性,在这种情况下非常简单:
void Context_ObjectMaterialized(object sender, ObjectMaterializedEventArgs args) 
{
    if (args.Entity is User) {        
        User user = (User)args.Entity;
        user.LastLoginDate = this.Utils
                .Where(u => u.UserID == user.UserID)
                .Max(u => u.LoginDate);
    }
}


希望这可以帮助。

关于sql-server - 如何向我的 EF4 模型添加计算列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3756082/

相关文章:

c# - IDENTITY_INSERT 设置为 OFF - Visual Studio

c# - EF 对象包装器围绕数据库/域模型中的原始类型

sql - 获取日期 SQL Server 的最大可能时间

sql-server - 带有空格的不同计数行为

entity-framework - 使用 StructureMap 处理 DbContext 异常

c# - Visual C# 和 SQL Server 无法一起正常工作//文件已在使用中

entity-framework - EF4中映射片段的问题

c# - EF 中的模型优先与数据优先

c# - 根据其他两列中的值透视一列中的行值

mysql - 每个类别仅显示 2 个软件