实体框架:具有复合键作为PK / FK的实体抛出异常

时间:2013-07-12 09:15:49

标签: entity-framework ef-code-first composite-key invalidoperationexception

在escalado上,抛出异常。它抛出或不包括在内。

static void Main(string[] args)
{
    try
    {                
        using (var context = new CKContext())
        {                    
            var servReprosWithIncludes = context.ServicioRepro
                                                .Include(p => p.Categoria)                                                        
                                                .ToList();
            var escalado = context.EscaladoPrecio
                                    //.Include(p => p.Servicio)
                                    .ToList();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

InvalidOperationException:作为对象键的一部分的属性的值与ObjectContext中存储的相应属性值不匹配。如果属于键的属性返回不一致或不正确的值,或者在对属于键的属性进行更改后未调用DetectChanges,则会发生这种情况。

EscaladoPrecio的映射:

public class EscaladoPrecioMapping : EntityTypeConfiguration<EscaladoPrecio>
{
    public EscaladoPrecioMapping()
    {
        base.HasKey(p => new { p.Desde, p.Hasta, p.ServicioReproId });            
        base.HasRequired(p => p.Servicio)
            .WithMany()
            .HasForeignKey(p => p.ServicioReproId);
        base.ToTable("PreciosServicioReprografia");
    }
}

实体ServicioRepro是TPT层次结构的一部分。看起来像:

public class ServicioRepro : Producto
{        
    public bool IncluirPrecioClick { get; set; }

    public bool IncluirPrecioPapel { get; set; }

    public bool HayPapel { get; set; }

    public bool HayImpresion { get; set; }

    public bool PrecioPorVolumen { get; set; }

    //public virtual ICollection<EscaladoPrecio> EscaladoPrecio { get; set; }

    public virtual CategoriaServicioRepro Categoria { get; set; }        

    public virtual ServicioReproFacturacionType ServicioReproFacturacionType { get; set; }      
}

在这个实体上你看不到密钥,因为基础实体Producto拥有密钥。

实体EscaladoPrecio有3个PK:desde,hasta和Servicio。 Servicio是PK和FK。 实体看起来像(方法,覆盖和成员已被删除以减少代码):

public class EscaladoPrecio : IComparable<EscaladoPrecio>, IComparable<int>, IComparable, IEntity
{
    #region Declarations

    private int _desde;
    private int _hasta;
    private double _precio;
    private int _cada;

    #endregion Declarations

    #region Constructor

    public EscaladoPrecio()
        : this(1, 1, 0, 0)
    { }

    public EscaladoPrecio(int desde, int hasta, double precio)
        : this(desde, hasta, precio, 0)
    { }

    public EscaladoPrecio(int desde, int hasta, double precio, int cada)
    {
        _desde = desde;
        _hasta = hasta;
        _precio = precio;
        _cada = cada;
    }

    #endregion Constructor

    #region Properties

    public int Desde
    {
        get
        {
            return _desde;
        }
        set
        {
            _desde = value;
        }
    }

    public int Hasta
    {
        get
        {
            return _hasta;
        }
        set
        {
            _hasta = value;
        }
    }

    public double Precio
    {
        get
        {
            return _precio;
        }
        set
        {
            _precio = value;
        }
    }

    public int Cada
    {
        get
        {
            return _cada;
        }
        set
        {
            _cada = value;
        }
    }

    #endregion Properties           

    private int _ServicioReproId;
    public int ServicioReproId
    {
        get
        {
            if (Servicio != null)
            {
                _ServicioReproId = Servicio.Id;
                return Servicio.Id;
            }
            else
                return 0;
        }
        set
        {
            _ServicioReproId = value;
        }

    }

    public virtual ServicioRepro Servicio { get; set; }
}

为什么抛出异常?

2 个答案:

答案 0 :(得分:0)

尝试初始化Escalade Precio()

类的构造函数中的虚拟属性

答案 1 :(得分:0)

你为什么这样做:

public int ServicioReproId
{
    get
    {
        if (Servicio != null)
        {
            _ServicioReproId = Servicio.Id;
            return Servicio.Id;
        }
        else
            return 0;
    }
    set
    {
        _ServicioReproId = value;
    }
}

您的关键属性ServicioReproId的一部分可能会返回0,尽管它已加载(并存储在上下文中),其值为!= 0(可能)。我认为异常的这一部分是指这个问题:“如果作为密钥一部分的属性返回不一致或不正确的值,就会发生这种情况。

最好留一个自动财产:

public int ServicioReproId { get; set; }