如果我在模型中有两个属性将另一个表作为外键引用,则似乎有问题。引擎为它们分配了意外的奇怪的列名,结果我得到一个SQL错误。让我展示我的源代码。
create table Units
(
UnitID int identity
constraint PK_Units primary key,
AspNetUserID nvarchar(128) not null
constraint FK_Units_AspNetUserId references AspNetUsers(Id),
[Name] nvarchar(255) not null
);
create unique index UIX_Units_AspNetUserID_Name
on Units(AspNetUserID, [Name]);
create table Products
(
ProductID int identity
constraint PK_Products primary key,
BusinessID int not null
constraint FK_Products_BusinessID references Businesses(BusinessID),
SKU nvarchar(31) null,
[Name] nvarchar(255) not null,
AdditionalName nvarchar(255) null,
UnitID int not null
constraint FK_Products_UnitID references Units(UnitID),
UnitPrice decimal(12, 2) not null,
TareUnitID int null
constraint FK_Products_TareUnitID references Units(UnitID),
UnitsInTare decimal(12, 2) null,
DefTaxRateID int null
constraint FK_Products_DefTaxRateID references TaxRates(TaxRateID)
);
create unique index UIX_Products_BusinessID_SKU_Name
on Products(BusinessID, SKU, [Name]);
VS引擎生成的模型。如您所见,Products
表两次引用Units
表(UnitID
和TareunitID
)。
public partial class Product
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Product()
{
this.InvoiceItems = new HashSet<InvoiceItem>();
}
public int ProductID { get; set; }
public int BusinessID { get; set; }
public string SKU { get; set; }
public string Name { get; set; }
public string AdditionalName { get; set; }
public int UnitID { get; set; }
public decimal UnitPrice { get; set; }
public Nullable<int> TareUnitID { get; set; }
public Nullable<decimal> UnitsInTare { get; set; }
public Nullable<int> DefTaxRateID { get; set; }
public virtual Business Business { get; set; }
public virtual TaxRate TaxRate { get; set; }
public virtual Unit Unit { get; set; }
public virtual Unit Unit1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
}
我也有以下部分类。
[MetadataType(typeof(UnitMetadata))]
public partial class Unit : BasePartialModelClass { }
[MetadataType(typeof(ProductMetadata))]
public partial class Product : BasePartialModelClass { }
最后,我有以下元数据类。
public class UnitMetadata
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UnitID { get; set; }
[Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "ThisFieldIsRequired")]
[StringLength(128, MinimumLength = 1, ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "MustBeMax128Characters")]
public string AspNetUserID { get; set; }
[Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "ThisFieldIsRequired")]
[StringLength(255, MinimumLength = 1, ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "MustBeMax255Characters")]
[Display(Name = "Name", ResourceType = typeof(GlobalRes))]
public string Name { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<Product> Products1 { get; set; }
}
public class ProductMetadata
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ProductID { get; set; }
[Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "ThisFieldIsRequired")]
public int BusinessID { get; set; }
[StringLength(31, ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "MustBeMax31Characters")]
[Display(Name = "UID", ResourceType = typeof(GlobalRes))]
public string SKU { get; set; }
[Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "ThisFieldIsRequired")]
[StringLength(255, MinimumLength = 1, ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "MustBeMax255Characters")]
[Display(Name = "Name", ResourceType = typeof(GlobalRes))]
public string Name { get; set; }
[StringLength(255, MinimumLength = 1, ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "MustBeMax255Characters")]
[Display(Name = "AdditionalName", ResourceType = typeof(GlobalRes))]
public string AdditionalName { get; set; }
[ForeignKey("Unit")]
public int UnitID { get; set; }
[Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "ThisFieldIsRequired")]
[Display(Name = "UnitPrice", ResourceType = typeof(GlobalRes))]
public decimal UnitPrice { get; set; }
[ForeignKey("Unit1")]
public Nullable<int> TareUnitID { get; set; }
[Display(Name = "UnitsInTare", ResourceType = typeof(GlobalRes))]
public Nullable<decimal> UnitsInTare { get; set; }
[ForeignKey("TaxRate")]
[Display(Name = "DefTaxRateID", ResourceType = typeof(GlobalRes))]
public Nullable<int> DefTaxRateID { get; set; }
public virtual Business Business { get; set; }
public virtual TaxRate TaxRate { get; set; }
[ForeignKey("UnitID")]
public virtual Unit Unit { get; set; }
[ForeignKey("TareUnitID")]
public virtual Unit Unit1 { get; set; }
public virtual ICollection<InvoiceItem> InvoiceItems { get; set; }
}
当我尝试使用产品创建视图时,出现错误。
似乎,生成的SQL查询有问题。因此,我使用了XEvents并查看了查询。
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[BusinessID] AS [BusinessID],
[Extent1].[SKU] AS [SKU],
[Extent1].[Name] AS [Name],
[Extent1].[AdditionalName] AS [AdditionalName],
[Extent1].[UnitID] AS [UnitID],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[TareUnitID] AS [TareUnitID],
[Extent1].[UnitsInTare] AS [UnitsInTare],
[Extent1].[DefTaxRateID] AS [DefTaxRateID],
[Extent1].[Unit_UnitID] AS [Unit_UnitID],
[Extent1].[Unit_UnitID1] AS [Unit_UnitID1]
FROM
[dbo].[Products] AS [Extent1]
ORDER BY
ROW_NUMBER() OVER (ORDER BY [Extent1].[Name] ASC)
OFFSET 0 ROWS FETCH NEXT 20 ROWS ONLY
问题是,如何使其正常工作?为什么将这些列放入查询中?请注意,
TareUnitID int null
constraint FK_Products_TareUnitID references Units(UnitID),
正常工作,没问题。我只遇到过两次引用的Unit
问题。