C# 实体框架中存储过程的返回值映射

C# 实体框架中存储过程的返回值映射,c#,stored-procedures,entity-framework-4,mapping,C#,Stored Procedures,Entity Framework 4,Mapping,我正在使用EntityFramework调用一个存储过程。但我在部分实体类中设置的自定义属性为null。 我的edmx中有实体(我称之为edmx,我不知道该怎么称呼它)。例如,我的数据库中有一个“User”表,所以我的实体上有一个“User”类。 我有一个名为GetUserById(@userId)的存储过程,在这个存储过程中,我编写了一个基本的sql语句,如下所示 "SELECT * FROM Users WHERE Id=@userId" User user = Context.SP_Ge

我正在使用EntityFramework调用一个存储过程。但我在部分实体类中设置的自定义属性为null。 我的edmx中有实体(我称之为edmx,我不知道该怎么称呼它)。例如,我的数据库中有一个“User”表,所以我的实体上有一个“User”类。 我有一个名为GetUserById(@userId)的存储过程,在这个存储过程中,我编写了一个基本的sql语句,如下所示

"SELECT * FROM Users WHERE Id=@userId"
User user = Context.SP_GetUserById(123456);
SELECT *, dbo.ConcatRoles(U.Id) AS RolesAsString
    FROM membership.[User] U
    WHERE Id = @id
在我的edmx中,我进行函数导入以调用此存储过程,并将其返回值设置为Entities(也可以从dropdownlist中选择User)。当我像下面这样调用存储过程时,它工作得非常好

"SELECT * FROM Users WHERE Id=@userId"
User user = Context.SP_GetUserById(123456);
SELECT *, dbo.ConcatRoles(U.Id) AS RolesAsString
    FROM membership.[User] U
    WHERE Id = @id
但我向存储过程添加了一个自定义的新列,以返回另一列,如下所示

"SELECT * FROM Users WHERE Id=@userId"
User user = Context.SP_GetUserById(123456);
SELECT *, dbo.ConcatRoles(U.Id) AS RolesAsString
    FROM membership.[User] U
    WHERE Id = @id
现在,当我从SSMS执行它时,名为RoleSassString的新列出现在结果中。 为了在实体框架上实现这一点,我在我的用户类中添加了一个名为RolesAsString的新属性,如下所示

public partial class User
    {
        public string RolesAsString{ get; set; }
    }
但是当我调用这个字段时,它不是由存储过程填充的。 我查看SP_GetUserById的映射详细信息窗口,该窗口上没有映射。我想添加,但窗口是只读的,我无法映射它。我查找了edmx的源代码,但找不到有关SP映射的任何信息


如何映射此自定义字段?

尝试在模型浏览器中将属性添加到用户实体。如果在模型中定义,而不是作为分部类,它可能会工作。。。或者,最后,最简单的方法可能是让它返回到实体,并将SP结果转换为用户结果,作为最后的手段


HTH。

您必须为SP创建复杂类型,而不是使用分部类。

非常旧的线程,但我今天遇到了这个问题

一个区别是,我没有将SP导入dbContext,而是选择使用SQLQuery返回联系人实体列表

var allContacts = _dbContext.Database.SqlQuery<Contacts> 
("CRM.GetAllContactsForCustomer @customerID, param1).ToList();
执行SP时不会填充此属性,这与在dbContext中使用导入的SP时相同

出于某种原因,我想到了为联系人创建一个包装类来保存额外属性的想法

public class ExtendedContacts : Contacts
{
    public new EnumContactOrigin ContactOrigin { get; set; }
}
你猜怎么着,它起作用了!ContactOrigin现在已正确填充

var allContacts = _dbContext.Database.SqlQuery<ExtendedContacts> 
("CRM.GetAllContactsForCustomer @customerID, param1).ToList();
var allContacts=\u dbContext.Database.SqlQuery
(“CRM.GetAllContactsForCustomer@customerID,param1).ToList();
在我的例子中,我同意它是一个包装类,因为我只使用联系人列表在网格中显示


我很想知道为什么这样做?是否有另一种方法可以在不需要这个ExtendedContacts类的情况下将额外属性检索到Contacts中。

首先,不要调用存储过程-该命名是为Microsoft保留的。第二,不要在存储过程中执行
SELECT*FROM…
。感谢您的评论,为什么您说不要调用“SELECT*”表示写入所有列名称,如“SELECT Id、name、Email等”,。。。。“?是的-当字段添加到DB时,它可以防止额外的字段返回,这可能会破坏DAL,因为它不需要这些字段。切勿在任何地方使用
SELECT*
。现在,关于这个问题-您是否在模型浏览器中更新了函数导入?是的,我在模型浏览器中更新了它,但什么也没发生。我还读到,实体框架不寻找分部类,因此它不会将“RolesAsString”列映射到实体属性。有人知道这一点吗?我有完全相同的情况正在进行,我想知道是否有一个不同的方式来做这件事。