EF Core 3.0을 사용하여 SQL Server 저장 프로 시저의 데이터를 Recipient
. Recipient
모델은 정의 된 속성의 부부가 EnvelopeId
및 Name
저장 프로 시저에서 반환되지 않습니다. 를 사용하여 저장 프로 시저를 호출 FromSqlInterpolated
하면 오류 메시지가 나타납니다.
필수 열 'EnvelopeId1'이 'FromSql'작업의 결과에 없습니다.
EF Core 설명서에서 읽은 내용에서 [NotMapped]
해당 속성에 특성을 추가 할 수 있어야 하며 EF Core는 데이터베이스에서 읽거나 쓰는 동안 속성을 무시할 수 있어야합니다. 맞습니까? 불행히도 그것은 나를 위해 작동하지 않으며 위의 오류가 발생합니다.
저장 프로 시저에 두 개의 열을 추가하고 [NotMapped]
개체 모델에서 특성을 제거하면 모든 것이 제대로 작동합니다. 이것은 내 다른 열 / 속성 이름이 올바르게 일치하고 어디에도 오타가 없음을 증명합니다.
DbQuery
대신 을 사용 하는 제안을 보았지만 DbSet
더 이상 사용되지 않으므로 사용하고 싶지 않습니다. 저장 프로 시저 결과 집합과 정확히 일치하는 속성을 가진 두 가지 개체 모델 사용에 대한 제안을 보았습니다. 내가 여기서 뭘 잘못하고 있니?
내 개체 모델 :
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MyNamespace.Models
{
public class Recipient
{
[Key]
public long RecipientId { get; set; }
[NotMapped]
public Guid? EnvelopeId { 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() { }
}
}
내 DB 컨텍스트 :
using Microsoft.EntityFrameworkCore;
using MyNamespace.Models;
namespace MyNamespace.Data
{
public class MyDbContext : DbContext
{
public virtual DbSet<Recipient> Recipient { get; set; }
public virtual DbSet<Envelope> Envelope { get; set; }
public virtual DbSet<Template> Template { get; set; }
public MyDbContext (DbContextOptions<MyDbContext> options) : base(options)
{ }
}
}
내 실패 코드 :
FormattableString sql = $"EXEC dbo.MyStoredProcedure @Param1={param1}, @Param2={param2}";
var result = await MyDbContext.Recipient.FromSqlInterpolated(sql).ToListAsync();
# 1 편집 ...
Envelope
개체 모델 :
public class Envelope
{
[Key]
public Guid EnvelopeId { get; set; }
public string Status { get; set; }
public DateTime StatusDate { get; set; }
public DateTime StatusPollDate { get; set; }
[NotMapped]
public List<Recipient> Recipients { get; set; }
public Envelope() {
Recipients = new List<Recipient>();
StatusPollDate = DateTime.Parse("1753-01-01");
}
}
저장 프로 시저 결과 집합 스키마 :
[RecipientId] bigint,
[Type] varchar(20),
[UserId] varchar(50),
[Email] varchar(100),
[RoleName] varchar(100),
[RoutingOrder] int,
[Status] varchar(13),
[StatusDate] datetime
일부 답변과 주석을 읽은 후 EF Recipient
가 Envelope
개체 의 자식 임을 인식하기 때문에 그림자 속성이 생성된다는 것을 깨달았습니다 . 솔직히 말해서, 난 정말 해야 인클루드 EnvelopeId
결과 집합 (및 제거에 [NotMapped]
진정 EF 코어를). 내가 EnvelopeId
저장 프로 시저의 결과 집합에서 반환하지 않은 유일한 이유는 시작하기 위해 입력 매개 변수로 전달했고, 무언가를 전달하고 각 결과에서 다시 가져 오는 데 네트워크 리소스를 낭비하고 있다고 생각했기 때문입니다. 기록을 세우십시오.
이제 어디서 EnvelopeId1
왔는지 모르겠지만 오류 메시지가 언급 한 것입니다. 내 개체 모델과 저장 프로 시저 결과 집합 스키마에서 볼 수 있듯이 EnvelopeId
. 내 가장 좋은 추측은 EF Core가 섀도우 속성을 만들기로 결정했을 때 EnvelopeId
이미 개체 모델에 있었기 때문에 사용할 수 없었기 때문에 호출 된 속성 을 만든 EnvelopeId1
다음 저장 프로 시저의 결과 집합에있을 것으로 예상했습니다. .
이 오류 메시지에는 두 가지 이유가 있습니다.
필수 열 'EnvelopeId1'이 'FromSql'작업의 결과에 없습니다.
분명한 것은 SQL 결과 집합의 모든 열에 대해 수화하려는 개체 그래프에 해당 속성이 있어야한다는 것입니다.이 경우 Recipient
클래스에는 EnvelopeId1
.
쿼리가 저장 프로 시저이기 때문에 SQL 결과를 다음과 같은 질문에 게시하는 것이 좋습니다. 그러면 개체 그래프에 매핑하려는 SQL 구조가 표시됩니다.
그 이유 EnvelopeId1
엔티티 프레임 워크가 만들어 때문에 개체 그래프에 SQL 테이블에 있지만은 그림자 속성 위해 당신이 속성을 정의하지 않은 것을 외국인 을 위해.
당신은 스키마를 나열하지 Envelope
않았지만 내 돈은 당신이 동등한 ICollection<Recipient>
재산 을 가지고 있다고 말합니다 .
에 대한 NotMapped
속성을 생성 EnvelopeId
하면이 스키마가 더 혼란스러워지고 대신 올바르게 매핑하거나 저장 프로 시저 출력에서 생략해야합니다.
FromSql
EF (.Net 또는 Core)에서 변형 을 사용 하려는 경우 데이터베이스에있는 열을 명시 적으로 생략하지 않는 한 데이터베이스의 Shadow 또는 Auto 외래 키 열로 인해 항상 스키마 클래스에서 탐색 속성을 정의해야 합니다. 하지만 당신의 스키마에는즉,
SELECT *
모든 열을 명시 적으로 정의 할 필요가 없습니다 .
해결 방법 1 : 저장 프로 시저 수정 받는 사람 테이블에서
반환되지 않도록 저장 프로 시저를 간단히 수정할 수 있습니다 EvelopeId1
.
솔루션 2 : 데이터 클래스에있는 모든 관계의 양쪽 끝에 대한 속성을 완전히 정의합니다.
여기서는 EnvelopeId1
마이그레이션이 필요하지 않도록 이름으로 사용 했지만이 이름을로 변경하는 것이 좋습니다. EnvelopeId
개인적으로 DB에있는 모든 필드의 존재를 사용합니다. 내 관계 중 일부가 부적절하게 정의되었음을 나타내는 숫자로 끝납니다.
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() { }
}
이는 Envelope 클래스에 다음 부분 정의와 유사한 정의가 있다는 가정을 기반으로합니다.
public class Envelope
{
[Key]
public Guid EnvelopeId { get; set; }
public virtual ICollection<Recipient> Recipients { get; set; } = new Hashset<Recipient>();
...
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다