繁体   English   中英

在EF6中使用枚举作为FK

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM