[英]Use enum as FK in EF6
我們有一個枚舉Supplier
但是現在我們還需要在這種關系上有一些域數據
所以在99.9%的域名代碼中我們對enum的操作就像product.Supplier == Suppliers.FedEx
但是現在我們還添加了product.SupplierInfo.CanAdjustPickupTime
,其中SupplierInfo
是一個實體而不僅僅是一個簡單的枚舉類型。
我試過這些配置
Property(p => p.Supplier)
.IsRequired()
.HasColumnName("SupplierId");
HasRequired(p => p.SupplierInfo)
.WithMany()
.HasForeignKey(p => p.Supplier); //I have also tried casting to int doing .HasForeignKey(p => (int)p.Supplier)
這將失敗
指定表達式的ResultType與所需類型不兼容。 表達式ResultType是'MyApp.Model.Suppliers',但所需的類型是'Edm.Int32'。 參數名稱:keyValues [0]
也試過了
Property(l => l.Supplier)
.IsRequired()
.HasColumnName("SupplierId");
HasRequired(p => p.SupplierInfo)
.WithMany()
.Map(m => m.MapKey("SupplierId"));
這樣就可以給人留下好處
在模型生成期間檢測到一個或多個驗證錯誤:
SupplierId:名稱:類型中的每個屬性名稱必須是唯一的。 已定義屬性名稱“SupplierId”。
我可以將SupplierId定義為使用HasForeignKey
的Property屬性然后我需要更改為.SuppliedId == (int)Suppliers.FedEx
等不是真正的解決方案。
我還可以添加一個使用SupplierId屬性作為支持字段的屬性枚舉,但這不適用於Expressions,因為它需要使用實際映射的數據庫屬性
有任何想法嗎?
我有課:
public class Agreement
{
public int Id { get; set; }
public AgreementStateTypeEnum AgreementStateId { get; set; }
}
public class AgreementState
{
public int Id { get; set; }
public string Title { get; set; }
}
背景:
public class AgreementContext :DbContext
{
public AgreementContext() : base("SqlConnection") { }
public DbSet<Agreement> Agreements { get; set; }
}
在方法OnModelCreating我什么都沒寫。 我的枚舉:
public enum AgreementStateTypeEnum : int
{
InReviewing = 1,
Confirmed = 2,
Rejected = 3
}
在數據庫中:在表中協議我有外鍵AgreementStateId - 它是表AgreementState的鏈接。 一切正常。 例如:
var temp = context.Agreements.First(x => x.AgreementStateId == AgreementStateTypeEnum.Confirmed);
我用enum怎么外鍵。
最后我發現了問題。 (我使用的是EF6,.NET 4.5)因此,如果在代碼中創建類型Enum,則無法與其他屬性虛擬創建關系。
//This is wrong, when do you create a foreignkey using a type enum
//Do You should remove that's code on in your class Map.
HasRequired(p => p.SupplierInfo)
.WithMany()
.HasForeignKey(p => p.Supplier); //I have also tried casting to int doing
.HasForeignKey(p => (int)p.Supplier)
如果您創建了類型枚舉,則意味着您不需要表格返回數據來進行EF中的連接。 所以,正確的代碼是:
public class MyClass{
public enum myEnumType {
FedEx,
Olther
}
public int id {get;set;}
public myEnumType Supplier {get;set;}
}
//My class Map (using Fluent...)
public class MyClassMap {
HasKey(t => t.Id);
Property(t => t.Id).HasColumnName("Id");
//The type [supplier] should be [int] in database.
Property(t => t.Supplier).HasColumnName("supplier");
//That's all, you don't need write relationship, int this case
//Because, when the data returns, the EF will to do the conversion for you.
}
我希望這很有用
我發現處理此方案的最佳方法是將供應商映射為常規域對象,並創建單獨的已知供應商ID類。
public class KnownSupplierIds
{
public const int FedEx = 1;
public const int UPS = 2;
// etc.
}
if (product.Supplier.SupplierId == KnownSupplierIds.Fedex) { ... };
當您的代碼需要檢查供應商時,它可以比較ID; 當您需要域模型中的其他信息時,您只需加載供應商。 我更喜歡使用一類常量而不是枚舉的原因是該模式也適用於字符串比較,並且不需要強制轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.