我有两个使用Entity Framework 7的简单类,一切都在所有类上正常工作,除了一个实例框架生成一个与现有列同名的新备用密钥的情况。
Invoice.cs
namespace Arinsys.Accounts
{
[Table(name: "Invoice", Schema = "Arinsys_Accounts")]
public class Invoice
{
public long ID { get; set; }
public string InvoiceID { get; set; }
public long? CustomerUID { get; set; }
public long? EmployeeUID { get; set; }
public DateTime BillDateTime { get; set; }
public long Amount { get; set; }
public long? Discount { get; set; }
public string DiscountReason { get; set; }
public string CouponID { get; set; }
public long Charges { get; set; }
public string ChargesReason { get; set; }
public long Tax { get; set; }
public string TaxType { get; set; }
public long FinalAmount { get; set; }
public string Status { get; set; }
public string Remarks { get; set; }
[ForeignKey("CustomerUID")]
public virtual CRM.User Customer { get; set; }
[ForeignKey("EmployeeUID")]
public virtual CRM.User BilledBy { get; set; }
public virtual ICollection<InvoiceItems> Items { get; set; }
public virtual ICollection<Payments> Payments { get; set; }
}
}
生成的发票表代码
CREATE TABLE [Arinsys_Accounts].[Invoice] (
[ID] BIGINT IDENTITY (1, 1) NOT NULL,
[Amount] BIGINT NOT NULL,
[BillDateTime] DATETIME2 (7) NOT NULL,
[Charges] BIGINT NOT NULL,
[ChargesReason] NVARCHAR (MAX) NULL,
[CouponID] NVARCHAR (MAX) NULL,
[CustomerUID] BIGINT NULL,
[Discount] BIGINT NULL,
[DiscountReason] NVARCHAR (MAX) NULL,
[EmployeeUID] BIGINT NULL,
[FinalAmount] BIGINT NOT NULL,
[InvoiceID] NVARCHAR (MAX) NOT NULL,
[InvoiceID1] NVARCHAR (450) NOT NULL,
[Remarks] NVARCHAR (MAX) NULL,
[Status] NVARCHAR (MAX) NULL,
[Tax] BIGINT NOT NULL,
[TaxType] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_Invoice] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [AK_Invoice_InvoiceID1] UNIQUE NONCLUSTERED ([InvoiceID1] ASC),
CONSTRAINT [FK_Invoice_User_CustomerUID] FOREIGN KEY ([CustomerUID]) REFERENCES [Arinsys_CRM].[User] ([ID]),
CONSTRAINT [FK_Invoice_User_EmployeeUID] FOREIGN KEY ([EmployeeUID]) REFERENCES [Arinsys_CRM].[User] ([ID])
);
InvoiceItems.cs
namespace Arinsys.Accounts
{
[Table(name: "InvoiceItems",Schema = "Arinsys_Accounts")]
public class InvoiceItems
{
public long ID { get; set; }
public string InvoiceID { get; set; }
public string ItemID { get; set; }
public int Quantity { get; set; }
public int Price { get; set; }
public int Discount { get; set; }
public string Reason { get; set; }
public int Amount { get; set; }
public string Remarks { get; set; }
[ForeignKey("InvoiceID")]
public virtual Invoice Invoice { get; set; }
}
}
生成InvoiceItems表代码
CREATE TABLE [Arinsys_Accounts].[InvoiceItems] (
[ID] BIGINT IDENTITY (1, 1) NOT NULL,
[Amount] INT NOT NULL,
[Discount] INT NOT NULL,
[InvoiceID] NVARCHAR (450) NULL,
[ItemID] NVARCHAR (MAX) NULL,
[Price] INT NOT NULL,
[Quantity] INT NOT NULL,
[Reason] NVARCHAR (MAX) NULL,
[Remarks] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_InvoiceItems] PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_InvoiceItems_Invoice_InvoiceID] FOREIGN KEY ([InvoiceID]) REFERENCES [Arinsys_Accounts].[Invoice] ([InvoiceID1])
);
注意发票表中的InvoiceID1列,它是自动创建的,我不需要它。由于这些模型在库中,即它们就像模板,实际的dbcontext将在应用程序中,我不希望最终开发人员担心这些事情,所以流畅的API in OnModelCreating不是一个选项。
关于下一个显而易见的问题,我们将如何管理引用,整体结构和接口的设计方式应该得到解决。无论如何,讨论将超出当前问题的范围。
我同意,我可以在InvoiceItems表中看到外键设置为InvoiceID1,但我希望它链接到Invoice Table中的ID列,如果我添加[InverseProperty(“ID”)]属性以及现有的[ForeignKey (“InvoiceID”)] InvoiceItems类中Invoice对象的属性显示错误
ArgumentNullException:值不能为null。参数名称:type
在撰写本文时,实体框架仍然很新,文档仍然不完整,Stackoverflow和其他地方的所有答案都说明了如何做到这一点,即如何创建备用/唯一密钥,但不幸的是我找不到任何答案如何防止它。
编辑:虽然这个问题在我看来是一个编程错误,但是我们已经收到了一些很好的答案,例如: @Steve Greene在EF SQL中发布了关于字符串长度限制的内容,这可能对未来的读者有所帮助,所以我将问题保留原样答案 0 :(得分:1)
EF(SQL)不能将超过900字节的字符串(450 unicode)编入索引,因此它会为您创建一个字符串。将您的模型更改为:
[StringLength(450)]
public string InvoiceID { get; set; }
或者使用类似的流利命令来限制它。 Entity Framework code first unique column
答案 1 :(得分:1)
问题在于您说InvoiceItem
有一个带有外键的引用(Invoice
)(InvoiceID
,类型为string
)。
然而,ID
的{{1}}是Invoice
,而不是long
,因此它会使用自己的字符串键来符合您的要求。
我的猜测:如果您将string
中的public string InvoiceID { get; set; }
更改为:InvoiceItem
,则应该停止创建密钥,此外,您实际上会获得正确的外键。