问题描述
我在sql InvoiceHeader
和InvoiceLines
中有两个表,它们具有一对多的关系,其中四列用作外键。我很容易从数据库生成实体对象,并且可以查询InvoiceHeader
对象,而不会出现问题。
当我在查询中包括InvoiceLines
或尝试单独查询它们时,EF生成的结果sql在select语句中包括InvoiceHeader
表名和每个键列作为fieldName
(示例InvoiceHeader.StoreID
作为InvoiceHeaderStoreID
包含在select语句中)。
脚手架生成的对象和上下文构建:
InvoiceHeader
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace BackOfficesql.Data.Models
{
public partial class InvoiceHeader
{
public InvoiceHeader()
{
InvoiceLines = new HashSet<InvoiceLines>();
}
[Key]
[Column("StoreID")]
public short StoreId { get; set; }
[Key]
[Column("CashRegisterID")]
public short CashRegisterId { get; set; }
[Key]
[Column("ShiftCounterID")]
public short ShiftCounterId { get; set; }
[Key]
[Column("InvoiceID")]
public short InvoiceId { get; set; }
[Column("TransactionTypeID")]
public short TransactionTypeId { get; set; }
[Column("CashierID")]
public short? CashierId { get; set; }
[Column(TypeName = "datetime")]
public DateTime? SetupDate { get; set; }
public bool? Audited { get; set; }
[StringLength(50)]
public string AuditedBy { get; set; }
[Column("vendorID")]
public int? vendorId { get; set; }
[Column("POHeadID")]
public int? PoheadId { get; set; }
[StringLength(50)]
public string vendorInvoice { get; set; }
[Column(TypeName = "datetime")]
public DateTime? InvoiceDate { get; set; }
[Column("upsize_ts")]
public byte[] UpsizeTs { get; set; }
[ForeignKey(nameof(TransactionTypeId))]
[InverseProperty(nameof(TransType.InvoiceHeader))]
public virtual TransType TransactionType { get; set; }
[InverseProperty("InvoiceHeader")]
public virtual InvoiceTruckInfo InvoiceTruckInfo { get; set; }
[InverseProperty("InvoiceHeader")]
public virtual ICollection<InvoiceLines> InvoiceLines { get; set; }
}
}
发票行
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace BackOfficesql.Data.Models
{
public partial class InvoiceLines
{
[Key]
[Column("StoreID")]
public short StoreId { get; set; }
[Key]
[Column("CashRegisterID")]
public short CashRegisterId { get; set; }
[Key]
[Column("ShiftCounterID")]
public short ShiftCounterId { get; set; }
[Key]
[Column("InvoiceID")]
public short InvoiceId { get; set; }
[Key]
[Column("InvoiceLineID")]
public short InvoiceLineId { get; set; }
[Key]
[Column("DepartmentTypeID")]
public short DepartmentTypeId { get; set; }
[Key]
public int ItemId { get; set; }
[Column("DepartmentID")]
public short? DepartmentId { get; set; }
[Column("MeterID")]
public short? MeterId { get; set; }
[StringLength(100)]
public string Description { get; set; }
public double Quantity { get; set; }
[Column(TypeName = "money")]
public decimal ExtendedPrice { get; set; }
public bool? Taxable { get; set; }
public double? TaxRate { get; set; }
public short? PriceLevel { get; set; }
public double? AfterQuantity { get; set; }
[Column(TypeName = "money")]
public decimal? UnitCost { get; set; }
[Column("UPCCode")]
[StringLength(15)]
public string Upccode { get; set; }
public short? UpdateOnhand { get; set; }
[Column("TableID")]
public int? TableId { get; set; }
[Column("upsize_ts")]
public byte[] UpsizeTs { get; set; }
[ForeignKey("ShiftCounterId,CashRegisterId,InvoiceId,StoreId")]
[InverseProperty("InvoiceLines")]
public virtual InvoiceHeader InvoiceHeader { get; set; }
}
}
InvoiceHeader DBContext
public virtual DbSet<InvoiceHeader> InvoiceHeader { get; set; }
modelBuilder.Entity<InvoiceHeader>(entity =>
{
entity.HasKey(e => new { e.ShiftCounterId,e.CashRegisterId,e.InvoiceId,e.StoreId })
.HasName("aaaaaInvoiceHeader_PK");
entity.HasIndex(e => e.PoheadId)
.HasName("POHeadID");
entity.HasIndex(e => e.vendorId)
.HasName("vendorID");
entity.HasIndex(e => new { e.InvoiceDate,e.TransactionTypeId })
.HasName("IX_InvoiceHeader_InvoiceDate");
entity.HasIndex(e => new { e.ShiftCounterId,e.TransactionTypeId,e.StoreId })
.HasName("TransactionTypeID")
.IsUnique();
entity.Property(e => e.ShiftCounterId).HasDefaultValuesql("(0)");
entity.Property(e => e.CashRegisterId).HasDefaultValuesql("(0)");
entity.Property(e => e.InvoiceId).HasDefaultValuesql("(0)");
entity.Property(e => e.StoreId).HasDefaultValuesql("(0)");
entity.Property(e => e.Audited).HasDefaultValuesql("(0)");
entity.Property(e => e.AuditedBy).IsUnicode(false);
entity.Property(e => e.CashierId).HasDefaultValuesql("(0)");
entity.Property(e => e.InvoiceDate).HasDefaultValuesql("(getdate())");
entity.Property(e => e.PoheadId).HasDefaultValuesql("(0)");
entity.Property(e => e.SetupDate).HasDefaultValuesql("(getdate())");
entity.Property(e => e.TransactionTypeId).HasDefaultValuesql("(1)");
entity.Property(e => e.UpsizeTs)
.IsRowVersion()
.IsConcurrencyToken();
entity.Property(e => e.vendorId).HasDefaultValuesql("(0)");
entity.Property(e => e.vendorInvoice).IsUnicode(false);
entity.HasOne(d => d.TransactionType)
.WithMany(p => p.InvoiceHeader)
.HasForeignKey(d => d.TransactionTypeId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_InvoiceHeader_TransType");
});
DbContext
public virtual DbSet<InvoiceLines> InvoiceLines { get; set; }
modelBuilder.Entity<InvoiceLines>(entity =>
{
entity.HasKey(e => new { e.ShiftCounterId,e.InvoiceLineId,e.DepartmentTypeId,e.StoreId,e.ItemId });
entity.HasIndex(e => e.ItemId)
.HasName("ItemId");
entity.HasIndex(e => e.MeterId)
.HasName("IX_MeterID_ServerID");
entity.HasIndex(e => e.Upccode)
.HasName("UPCCode");
entity.HasIndex(e => e.UpdateOnhand)
.HasName("IX_UpdateOnhand");
entity.HasIndex(e => new { e.ShiftCounterId,e.StoreId })
.HasName("IX_InvoiceLines");
entity.HasIndex(e => new { e.StoreId,e.ShiftCounterId,e.InvoiceLineId })
.HasName("UK_InvoiceLines")
.IsUnique();
entity.Property(e => e.ShiftCounterId).HasDefaultValuesql("(0)");
entity.Property(e => e.CashRegisterId).HasDefaultValuesql("(0)");
entity.Property(e => e.InvoiceId).HasDefaultValuesql("(0)");
entity.Property(e => e.InvoiceLineId).HasDefaultValuesql("(0)");
entity.Property(e => e.DepartmentTypeId).HasDefaultValuesql("(0)");
entity.Property(e => e.StoreId).HasDefaultValuesql("(0)");
entity.Property(e => e.ItemId).HasDefaultValuesql("(0)");
entity.Property(e => e.AfterQuantity).HasDefaultValuesql("((-1))");
entity.Property(e => e.DepartmentId).HasDefaultValuesql("(0)");
entity.Property(e => e.Description).IsUnicode(false);
entity.Property(e => e.ExtendedPrice).HasDefaultValuesql("(0)");
entity.Property(e => e.MeterId).HasDefaultValuesql("(0)");
entity.Property(e => e.PriceLevel).HasDefaultValuesql("(0)");
entity.Property(e => e.Quantity).HasDefaultValuesql("(0)");
entity.Property(e => e.TaxRate).HasDefaultValuesql("(0)");
entity.Property(e => e.Taxable).HasDefaultValuesql("(0)");
entity.Property(e => e.UnitCost).HasDefaultValuesql("(0)");
entity.Property(e => e.Upccode).IsUnicode(false);
entity.Property(e => e.UpdateOnhand).HasDefaultValuesql("(0)");
entity.Property(e => e.UpsizeTs)
.IsRowVersion()
.IsConcurrencyToken();
entity.HasOne(d => d.InvoiceHeader)
.WithMany(p => p.InvoiceLines)
.HasForeignKey(d => new { d.ShiftCounterId,d.CashRegisterId,d.InvoiceId,d.StoreId })
.HasConstraintName("FK_InvoiceLines_InvoiceHeader");
});
测试实体查询:
Invoice = context.InvoiceHeader.Where(x => x.StoreId == 1 && x.CashRegisterId == 54 && x.ShiftCounterId == 1 && x.InvoiceId == 24)
// .Include(l => l.InvoiceLines) //Causes An exception
.Include(t => t.InvoiceTruckInfo)
.FirstOrDefault();
为找出问题所在,我能够查询InvoiceLines
实体并使用反射方法来找到EF生成的sql。
var query = context.InvoiceLines.Where(x => x.StoreId == 1 && x.CashRegisterId == 54 && x.ShiftCounterId == 1 && x.InvoiceId == 24);
var sql = query.Tosql();
SELECT [i].[ShiftCounterID],[i].[CashRegisterID],[i].[InvoiceID],[i].[InvoiceLineID],[i].[DepartmentTypeID],[i].[StoreID],[i].[ItemId],[i].[AfterQuantity],[i].[DepartmentID],[i].[Description],[i].[ExtendedPrice],[i].[InvoiceHeaderCashRegisterId],[i].[InvoiceHeaderInvoiceId],[i].[InvoiceHeaderShiftCounterId],[i].[InvoiceHeaderStoreId],[i].[MeterID],[i].[PriceLevel],[i].[Quantity],[i].[TableID],[i].[TaxRate],[i].[Taxable],[i].[UnitCost],[i].[UPCCode],[i].[UpdateOnhand],[i].[upsize_ts]
FROM [InvoiceLines] AS [i]
WHERE ((([i].[StoreID] = CAST(1 AS smallint))
AND ([i].[CashRegisterID] = CAST(54 AS smallint)))
AND ([i].[ShiftCounterID] = CAST(1 AS smallint)))
AND ([i].[InvoiceID] = CAST(24 AS smallint))
以下4列无效,如果我从上面的sql中删除它们,则可以无问题地运行SQL查询:
[i].[InvoiceHeaderCashRegisterId],
我已经尝试过对EF实用程序生成的实体进行各种修改,即使我在示例和文档中所看到的一切都使实体和上下文构建看起来正确。我不确定将表名和字段名结合使用的原因或原因,将其插入到生成的sql select语句中。
执行代码以查询InvoiceHeader
并包括执行的InvoiceLines
或InvoiceLines
查询时,毫无疑问地会抛出sql异常:
无效的列名'InvoiceHeaderCashRegisterId'。
无效的列名'InvoiceHeaderInvoiceId'。
无效的列名'InvoiceHeaderShiftCounterId'。
无效的列名'InvoiceHeaderStoreId'。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)