EF导航属性不工作

本文关键字:工作 属性 导航 EF | 更新日期: 2023-09-27 18:18:53

我有一个Card类:

public class Card
{
    public Card(){}
    [Key]
    [Required]
    public virtual int CardId { get; set; }
    [ForeignKey("StageId")]
    public virtual Stage Stage { get; set; }
    public int StageId { get; set; }
    }
}

和一个Stage class:

public class Stage
{
    [Key]
    public virtual int StageId { get; set; }
    [DataMember(EmitDefaultValue = true)]
    public string Name { get; set; }
    public long Ticks { get; set; }
    [NotMapped]
    public TimeSpan Span
    {
        get { return TimeSpan.FromTicks(Ticks); }
    }
    // Make sure that these stages are generated accordingly
    public static class Ids
    {
        // Zero
        public const int One = 1;
        // Ten Seconds
        public const int Two = 2;
        // One Minute
    }
}

在我的存储库服务中,我有一个AddCard方法:

public Card AddCard(Card card)
    {
        int parentId = 0;
        Set parentSet = null;
        if (card.ParentSetId.HasValue)
        {
            parentId = card.ParentSetId.Value;
            parentSet = GetSet(parentId);
        }
        card.ParentSet = parentSet;
        card.ParentSetId = parentSet.SetId;
        card.StageId = Stage.Ids.One;  // Set Id here with hopes of getting card.Stage to resolve as a nav property
        _db.Cards.Add(card);
        SaveChanges();
        return card;
    }

但是由于某种原因,我所有的Cards都有一个空值。舞台——何处卡。StageId总是一个整数。我试图让导航属性工作,所以我可以通过卡访问的阶段的属性。

我哪里做错了?

更新:

当我试图通过测试访问它们时,属性为null。首先,我创建卡片(在我的测试代码中):

 var cardDto = new CardDto  // Works!
            {
                Details = "Test Card",
            };
然后我把它发送到我的Dto服务(也在测试代码中):
 var fullCardDto = _service.AddCard(cardDto); // breaks because Stage is null when stageId is not

CardDto Class:

public class CardDto
{
    public CardDto(){}
    public CardDto(Card card)
    {
        CardId = card.CardId;
        Stage = card.Stage.Name;  // Fails here on its way back - creating the initial DTO works
        Details = card.Details;
    }
    [Key]
    [DataMember(EmitDefaultValue = true)]
    public int CardId { get; set; }

    [DataMember(EmitDefaultValue = true)]
    public string Stage { get; set; }
    [DataMember(IsRequired = false)]
    public string Details { get; set; }
    public Card ToEntity()
    {
        var newCard = new Card
            {
             CardId = CardId,
             Details = Details,
            };
        return newCard;
}

_service为DTO服务:

public CardDto AddCard(CardDto card)
    {
        return new CardDto(_repository.AddCard(card.ToEntity()));
    }

_repository代码在上面。

这在_repository调用中一直有效,但是如果我调试_repository。在调用SaveChanges()之后,StageId有了一个值,但是Stage没有。

卡片被传递回链,直到它应该再次转换为Dto,在那里由于null阶段而失败。

奇怪的是,这段代码在测试之外工作——如果我使用客户端来点击AddCard,我将得到一张没有任何错误的卡片。

EF导航属性不工作

要使延迟加载工作,您需要创建一个代理。如果你正在加载Card在EF中,您将自动收到一个封装在代理对象中的对象。你可以在这里做两件事
1. 要使用延迟加载,您可以创建一个像这样的代理,

public Card AddCard(Card card)
    {
        var cardProxy= _db.Cards.Create(); 
        //and copy all values from card to cardProxy here..
        int parentId = 0;
        Set parentSet = null;
        if (cardProxy.ParentSetId.HasValue)
        {
            parentId = cardProxy.ParentSetId.Value;
            parentSet = GetSet(parentId);
        }
        cardProxy.ParentSet = parentSet;
        cardProxy.ParentSetId = parentSet.SetId;
        cardProxy.StageId = Stage.Ids.One;  // Set Id here with hopes of getting card.Stage to resolve as a nav property
          SaveChanges();
        return cardProxy;
}
  1. 或者你可以使用显式加载,

    public Card AddCard(Card Card){int parentId = 0;设置parentSet = null;如果(card.ParentSetId.HasValue){parentId = card.ParentSetId.Value;parentSet = GetSet(parentId);}

            card.ParentSet = parentSet;
            card.ParentSetId = parentSet.SetId;
            card.StageId = Stage.Ids.One;  // Set Id here with hopes of getting card.Stage to resolve as a nav property
            _db.Cards.Add(card);
            SaveChanges();
            context.Entry(card).Reference(p => p.Stage).Load();//load stage here
           return card;
        }