使用存储过程时实体框架返回关联表的空值

问题描述 投票:0回答:1

我在 EF 中使用代码优先方法,我创建了一个存储过程来选择,当我运行它时,我从

User
表中获取值,但 FK 属性为空。

这是我的存储过程:

ALTER PROCEDURE rsm_Select
    @Id [int]
AS
BEGIN
    SET NOCOUNT ON;

    SELECT 
        u.*, p.*, ut.*
    FROM
        Users u
    LEFT JOIN
        UserProfiles p ON u.userProfile_Id = p.Id
    LEFT JOIN
        UserTypes ut ON u.UserType_Id = ut.Id
    WHERE
        u.Id = @Id;
END

我有三节课(

User, UserProfile, UserType
):

Public class User
{
    public int Id { set; get; }
    public string U_UserName { set; get; }
    public string U_UserPass { set; get; }
    public string U_Accountstat { set; get; }

    public virtual UserProfile UserProfile_Id { set; get; }
    public virtual UserType Usertype_Id { set; get; }
}

public class Admin : User
{
    //...
}

public class SuperAdmin : Admin
{
    //...
}

public Class UserType
{
    public int Id { set; get; }
    public string TypeName { set; get; }
}

public class UserProfile
{
    public int Id { set; get; }
    public string UFirstName { set; get; }
    public string ULastName { set; get; }
    public string UContact { set; get; }

    public virtual User U_Id { set; get; }
}

这些是我使用的类,根据它们,表将在数据库中创建。

User
表中,
ProfileID
UserTypeId
是外键。

现在

当我尝试执行存储过程时,我将在

UserProfile_ID
UserType_ID
中得到 null。

这是我的运行方式:

void Select(int userId)
{
    using (var context = new myCodeFirstApproach())
    {
        var Result = context.Database
                            .SqlQuery<User>("EXEC rsm_Select @Id", new SqlParameter("@Id", userId))
                            .ToList();
    }
}

当我调试结果时,我在

UserProfile_Id
UserType_Id
上得到 null,但我确实在其他字段中获得了值,例如
U_UserName
U_UserPass
U_Accountstat

当我在 SQL Server Management Studio 中运行存储过程时,它返回正确的结果,但在我的代码中却没有。

这里出了什么问题?

PS:用于更新、删除和创建的所有其他存储过程都工作正常。

我尝试更改存储过程,但结果仍然相同

c# winforms entity-framework ef-code-first entity
1个回答
0
投票

问题可能在于实体框架将存储过程结果映射到用户类的方式。该问题可能是由于存储过程结果和类属性之间的属性名称不匹配或由于不正确的映射配置造成的。

确保您的存储过程返回名称与 User、UserProfile 和 UserType 类中的属性匹配的列。例如:

SELECT 
    u.Id AS Id, 
    u.U_UserName AS U_UserName, 
    u.U_UserPass AS U_UserPass, 
    u.U_Accountstat AS U_Accountstat,
    p.Id AS UserProfile_Id,
    ut.Id AS UserType_Id
FROM Users u
LEFT JOIN UserProfiles p ON u.userProfile_Id = p.Id
LEFT JOIN UserTypes ut ON u.UserType_Id = ut.Id
WHERE u.Id = @Id;

确保 SQL 结果集中的属性名称与 C# 类中的属性名称匹配。

接下来,在您的 User 类中,确保外键属性(UserProfile_Id 和 Usertype_Id)与相关类(UserProfile 和 UserType)中的主键具有相同的类型:

public class User
{
    // Other properties...

    public virtual UserProfile UserProfile { get; set; } // Assuming UserProfile is a class
    public virtual UserType UserType { get; set; } // Assuming UserType is a class
}

调整存储过程执行以正确处理加载的实体:

void Select(int userId)
{
    using (var context = new myCodeFirstApproach())
    {
        var result = context.Database.SqlQuery<User>("EXEC rsm_Select @Id", new SqlParameter("@Id", userId)).ToList();

        // Access related entities (if needed)
        foreach (var user in result)
        {
            Console.WriteLine($"User: {user.U_UserName}");
            Console.WriteLine($"UserProfile ID: {user.UserProfile?.Id}"); // Access related UserProfile
            Console.WriteLine($"UserType ID: {user.UserType?.Id}"); // Access related UserType
        }
    }
}

确保 User 类中的属性(UserProfile 和 UserType)是虚拟的,以根据您的需要启用延迟加载或预先加载。

这应该有助于实体框架将存储过程的结果正确映射到 User 类并填充相关实体。如果仍然不起作用,则您的 EF 设置中可能存在其他配置或问题需要解决。

确保验证存储过程返回的结果的列名称与 C# 类中的属性匹配。另外,请确保在实体框架中正确配置实体之间的关系。如果问题仍然存在,请考虑检查 EF 配置或调试映射,以确保从存储过程中准确检索数据。

© www.soinside.com 2019 - 2024. All rights reserved.