如何使导航属性工作?

时间:2015-01-24 14:11:48

标签: c# entity-framework navigation-properties

我有以下实体:

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,并在以后的代码中使用myPremise检索myMeter.Premise

修改 通过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'前提'无效。在AssociationType'Preise_GasMeter'中输入FromRole'Premise_GasMeter_Target'的'GasMeter'必须与声明此NavigationProperty的类型'Meter'完全匹配。

这是否意味着我无法使用带继承的导航属性? 那我怎么解决我的问题呢?

2 个答案:

答案 0 :(得分:0)

我认为您需要为每个类添加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; }
}

答案 1 :(得分:0)

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

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);
}

SET

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

GET

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