Use enumeration as FK in EF6

We have a listing Supplier

But now we also need to have some Domain data regarding this relationship.

Thus, in 99.9% of the domain code, we perform enumeration operations, for example product.Supplier == Suppliers.FedEx

But now we have also added product.SupplierInfo.CanAdjustPickupTimewhere SupplierInfois Entity, and not just a simple enumeration type.

I tried these configs

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)

This will not succeed using

ResultType of the specified expression is incompatible with the required type. The ResultType expression is "MyApp.Model.Suppliers", but the required type is' Edm.Int32. Parameter Name: keyValues ​​[0]

Also tried

Property(l => l.Supplier)
    .IsRequired()
    .HasColumnName("SupplierId");

HasRequired(p => p.SupplierInfo)
    .WithMany()
    .Map(m => m.MapKey("SupplierId"));

This shutdown will give the good old

During model generation, one or more validation errors were detected:

SupplierId: Name: . 'SupplierId' .

SupplierId , HasForeignKey .SuppliedId == (int)Suppliers.FedEx .. .

, SupplierId , , DB.

?

+4
3

:

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 
 }

: StateId. .. . :

var temp = context.Agreements.First(x => x.AgreementStateId == AgreementStateTypeEnum.Confirmed);

enum .

0

, . ( EF6, NET 4.5) , Enum , .

//This is wrong, when do you create a foreignkey using a type  enum
//Do You should remove that 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)

, , tt 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 all, you don't need write relationship, int this case 
//Because, when the data returns, the EF will to do the conversion for you.

}

,

0

, , .

public class KnownSupplierIds
{
    public const int FedEx = 1;
    public const int UPS = 2;
    // etc.
}

if (product.Supplier.SupplierId == KnownSupplierIds.Fedex) { ... };

When your code needs to verify a provider, it can compare identifiers; when you need additional information from the domain model, you simply download the Provider. The reason I prefer to use the class of constants instead of enumeration is that the template also works for comparing strings, and there is no need to throw.

0
source

Source: https://habr.com/ru/post/1609584/


All Articles