【问题标题】:How do I get Navigation Properties working?如何让导航属性正常工作?
【发布时间】:2015-03-23 11:07:34
【问题描述】:

我有以下实体:

public abstract class Meter
{
    public int MeterId { get; set; }
    public string EANNumber { get; set; }
    public string MeterNumber { get; set; }
    [Required]
    public virtual Premise Premise { get; set; }
    public abstract void AddReading(CounterReading reading);
}

public class GasMeter : Meter
{
    public virtual Counter Counter { get; private set; }

    public override void AddReading(CounterReading reading)
    {
        Counter.Readings.Add(reading);
    }
}

public class Premise
{
    [Key]
    public int PremiseId { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }

    [Required]
    public virtual Address Address { get; set; }
    public string Type { get; set; }

    public virtual GasMeter GasMeter { get; set; }
}

GasMeterPremise 之间存在 1:1 的关系。

我必须做什么才能设置myPremise.GasMeter = myMeter,并在以后的代码中使用myMeter.Premise 检索myPremise

编辑 通过 Fluent API 进行如下设置时:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Premise>().HasOptional(p => p.GasMeter)
            .WithRequired(m => m.Premise);
    }

运行时出现以下异常:

EntityFramework.dll 中出现“System.Data.Entity.ModelConfiguration.ModelValidationException”类型的异常,但未在用户代码中处理

附加信息:在模型生成过程中检测到一个或多个验证错误:

前提:FromRole:NavigationProperty 'Premise' 无效。 AssociationType 'Premise_GasMeter' 中 FromRole 'Premise_GasMeter_Target' 的类型 'GasMeter' 必须与声明此 NavigationProperty 的类型 'Meter' 完全匹配。

这是否意味着我不能将导航属性与继承一起使用? 那我该如何解决我的问题呢?

【问题讨论】:

  • @GertArnold 请查看我的更新。
  • public virtual Premise Premise { get; set; } 应位于 GasMeterpublic virtual GasMeter GasMeter 应位于 public virtual Meter Meter
  • @GertArnold 是的,我把前提放在了我的 GasMeter 中。我有多个仪表(GasMeter、WaterMeter、ElectricityMeter),并希望在那里保持类型安全。
  • @GertArnold 将Premise 属性放在我的仪表上会使我的 MeterId 错误。 EF 不再自动增加 MeterId。

标签: c# entity-framework navigation-properties


【解决方案1】:

我认为您需要将 Id 添加到每个类以实现 PK/FK 关系

public abstract class Meter
{
   ....
    public int PremiseId
    public virtual Premise Premise { get; set; }
}

public class Premise
{
   ....
   public int GasMeterId
   public virtual GasMeter GasMeter{ get; set; }
}

【讨论】:

  • 将前提添加到计量表后,我仍然看不到前提中的计量表。即使有你的建议。
【解决方案2】:

您可能不需要将这两个实体作为虚拟属性链接在一起。尝试修改 Meter 类以保留 PremiseId,因为它是 Premise 表的主键,然后使用 Select(x =&gt; x.PremiseId == aMeter.PremiseId).SingleOrDefault() 获取 Premise 实体以获取映射到此 GasMeter 的 Premise

public abstract class Meter
{
    public int MeterId { get; set; }
    public string EANNumber { get; set; }
    public string MeterNumber { get; set; }
    public int PremiseId { get; set; }
    public abstract void AddReading(CounterReading reading);
}

设置

var aPremise = new Premise();
var aMeter = new GasMeter();
aPremise.GasMeter = aMeter;
aMeter.PremiseId = aPremise.PremiseId;

获取

var thePremise = _repository.Set<Premise>.Select(x => x.PremiseId == aMeter.PremiseId).SingleOrDefault();

【讨论】:

  • 这样使用它会破坏拥有导航属性的意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 1970-01-01
  • 2016-08-16
  • 2015-05-08
  • 2020-08-27
  • 2018-06-11
  • 2016-08-27
相关资源
最近更新 更多