模型中的两个外键引用同一张表

时间:2018-08-24 17:19:12

标签: c# sql-server entity-framework

如果我在模型中有两个属性将另一个表作为外键引用,则似乎有问题。引擎为它们分配了意外的奇怪的列名,结果我得到一个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表(UnitIDTareunitID)。

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问题。

0 个答案:

没有答案