C# a';的结果中不存在所需列;FromSql';操作和[NotMapped]没有帮助
我正在使用EF Core 3.0将数据从SQL Server存储过程提取到名为C# a';的结果中不存在所需列;FromSql';操作和[NotMapped]没有帮助,c#,sql-server,.net-core-3.0,ef-core-3.0,C#,Sql Server,.net Core 3.0,Ef Core 3.0,我正在使用EF Core 3.0将数据从SQL Server存储过程提取到名为收件人的对象模型中。Recipient模型定义了两个属性,EnvelopeId和Name,它们不是从存储过程返回的。当我使用SQLInterpolated调用存储过程时,会收到错误消息 “FromSql”操作的结果中不存在所需的列“Enveloped1” 根据我在EF Core文档中读到的内容,我应该能够为这些属性添加[NotMapped]属性,并且EF Core应该能够在读取或写入数据库时忽略它们,对吗?不幸的是,这
收件人
的对象模型中。Recipient
模型定义了两个属性,EnvelopeId
和Name
,它们不是从存储过程返回的。当我使用SQLInterpolated调用存储过程时,会收到错误消息
“FromSql”操作的结果中不存在所需的列“Enveloped1”
根据我在EF Core文档中读到的内容,我应该能够为这些属性添加[NotMapped]
属性,并且EF Core应该能够在读取或写入数据库时忽略它们,对吗?不幸的是,这对我不起作用,我得到了上面的错误
如果在存储过程中添加两列,并删除对象模型中的[NotMapped]
属性,则一切正常。这证明了我的其他列/属性名称匹配正确,并且没有任何拼写错误
我看到过使用DbQuery
而不是DbSet
的建议,但这种建议已被弃用,因此我不想使用它。我看到过使用两种不同对象模型的建议,其中一种具有与存储过程结果集完全匹配的属性,但这只会导致大量额外的模型。我做错了什么
我的对象模型:
使用系统;
使用System.ComponentModel.DataAnnotations;
使用System.ComponentModel.DataAnnotations.Schema;
名称空间MyNamespace.Models
{
公共类收件人
{
[关键]
公共长RecipientId{get;set;}
[未映射]
公共Guid?信封ID{get;set;}
公共字符串类型{get;set;}
公共字符串用户标识{get;set;}
公共字符串电子邮件{get;set;}
[未映射]
公共字符串名称{get;set;}
公共字符串RoleName{get;set;}
公共int路由顺序{get;set;}
公共字符串状态{get;set;}
公共日期时间状态日期{get;set;}
公共收件人(){}
}
}
我的数据库上下文:
使用Microsoft.EntityFrameworkCore;
使用MyNamespace.Models;
名称空间MyNamespace.Data
{
公共类MyDbContext:DbContext
{
公共虚拟数据库集收件人{get;set;}
公共虚拟数据库集信封{get;set;}
公共虚拟数据库集模板{get;set;}
公共MyDbContext(DbContextOptions):基本(选项)
{ }
}
}
我的失败代码:
FormattableString sql=$“EXEC dbo.MyStoredProcedure@Param1={Param1},@Param2={Param2}”;
var result=await MyDbContext.Recipient.FromSqlInterpolated(sql.toListSync();
编辑#1…
信封
对象模型:
公共类信封
{
[关键]
公共Guid信封ID{get;set;}
公共字符串状态{get;set;}
公共日期时间状态日期{get;set;}
公共日期时间状态PollDate{get;set;}
[未映射]
公共列表收件人{get;set;}
公函(){
收件人=新列表();
StatusPollDate=DateTime.Parse(“1753-01-01”);
}
}
存储过程结果集架构:
[RecipientId]bigint,
[Type]varchar(20),
[UserId]varchar(50),
[电子邮件]瓦查尔(100),
[RoleName]varchar(100),
[RoutingOrder]int,
[状态]瓦尔查尔(13),
[状态日期]日期时间
在阅读了一些答案和评论后,我意识到EF正在创建一个shadow属性,因为它识别出Recipient
是Envelope
对象的子对象。老实说,我真的应该在结果集中包含EnvelopeId
(并删除[NotMapped]
),以安抚EF Core。我没有在存储过程的结果集中返回EnvelopeId的唯一原因是,我首先将它作为输入参数传入,并认为传入某些内容然后在每个结果集记录中获取它是在浪费网络资源
现在我不知道Enveloped1从哪里来,但这就是错误消息所提到的。正如您在我的对象模型和存储过程结果集模式中所看到的,我只引用过
EnvelopeId
。我的最佳猜测是,当EF Core决定创建一个shadow属性时,它无法使用EnvelopeId
,因为我的对象模型中已经有了它,所以它创建了一个名为EnvelopeId 1
,然后期望它出现在存储过程的结果集中。产生此错误消息的原因有两个:
“FromSql”操作的结果中不存在所需的列“Enveloped1”
显而易见的一点是,对于SQL结果集中的每一列,必须在您试图创建的对象图中有相应的属性,在这种情况下,Recipient
类没有enveloped1
因为您的查询是一个存储过程,所以明智的做法是在类似这样的问题中发布SQL结果,因为它将显示您试图映射到对象图的SQL结构
EnvelopedId1
出现在SQL表中而不出现在对象图中的原因是实体框架为for创建了一个
您没有列出信封
的架构,但我的钱说您有一个等价的ICollection
属性
为EnvelopeId
创建NotMapped
属性只会使这个模式更加混乱,我们应该正确地映射它,或者从存储过程输出中省略它
如果要在EF(.Net或Core)中使用FromSql
变体,则应始终定义
public class Recipient
{
[Key]
public long RecipientId { get; set; }
public Guid? EnvelopeId1 { get; set; }
[ForeignKey(nameof(EnvelopeId1))]
public virtual Envelope Envelope { get; set; }
public string Type { get; set; }
public string UserId { get; set; }
public string Email { get; set; }
[NotMapped]
public string Name { get; set; }
public string RoleName { get; set; }
public int RoutingOrder { get; set; }
public string Status { get; set; }
public DateTime StatusDate { get; set; }
public Recipient() { }
}
public class Envelope
{
[Key]
public Guid EnvelopeId { get; set; }
public virtual ICollection<Recipient> Recipients { get; set; } = new Hashset<Recipient>();
...
}