Enum como Key in entity framework 5 lançando erro em muitos para muitos uniões
OK, isso é um pouco longo / obscuro, mas estou recebendo um erro estranho em uma situação específica em que uso um Enum como uma Table Key e tento consultar a tabela enquanto incluo mais de uma entidade relacionada many-to-many.
O erro, do código de exemplo abaixo é:
The type of the key field 'DietIs' is expected to be 'MvcApplication8.Models.DietIs', but the value provided is actually of type 'System.Int32'.
Em um projeto da web do .net 4.5, tenho a seguinte configuração de entidade:
public enum DietIs {
None,
Kosher,
Paleo,
Vegetarian
}
public class Diet {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public DietIs DietIs { get; set; }
public string Description { get; set; }
public virtual ICollection<Recipe> Recipes { get; set; }
public virtual ICollection<Menu> Menus { get; set; }
}
public class Recipe {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Diet> Diets { get; set; }
}
public class Menu {
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Diet> Diets { get; set; }
}
public class EnumTestContextInit : DropCreateDatabaseAlways<EnumTestContext> {}
public class EnumTestContext : DbContext {
public DbSet<Diet> Diets { get; set; }
public DbSet<Menu> Menus { get; set; }
public DbSet<Recipe> Recipes { get; set; }
public EnumTestContext() : base("EnumTestContext") {
Configuration.LazyLoadingEnabled = false;
Configuration.ProxyCreationEnabled = false;
}
}
No arquivo Global.asax.cs, inicializo o banco de dados:
Database.SetInitializer(new EnumTestContextInit());
using (var context = new EnumTestContext()) {
var noDiet = new Diet { DietIs = DietIs.None, Description = "Whatever you want" };
var paleoDiet = new Diet { DietIs = DietIs.Paleo, Description = "Like paleolithic peoples" };
var vegDiet = new Diet { DietIs = DietIs.Vegetarian, Description = "No meat" };
context.Menus.Add(new Menu { Name = "Cheese burger with Fries Menu", Diets = new List<Diet> { noDiet } });
context.Menus.Add(new Menu { Name = "Mammoth Steak Tartar with Nuts Menu", Diets = new List<Diet> { paleoDiet, noDiet } });
context.Menus.Add(new Menu { Name = "Soy Cheese Pizza Menu", Diets = new List<Diet> { vegDiet, noDiet } });
context.Recipes.Add(new Recipe {Name = "Cheese burger", Diets = new List<Diet> {noDiet}});
context.Recipes.Add(new Recipe { Name = "Mammoth Steak Tartar", Diets = new List<Diet> { paleoDiet, noDiet} });
context.Recipes.Add(new Recipe { Name = "Cheese Pizza", Diets = new List<Diet> { vegDiet, noDiet } });
context.SaveChanges();
}
Em seguida, tento consultar o banco de dados:
var context = new EnumTestContext();
var dietsWithMenusAndRecipes = context.Diets
.Include(e => e.Menus)
.Include(e => e.Recipes)
.ToList();
Outras consultas onde eu uso um único incluem carregar os dados esperados sem problemas. A consulta acima, com dois includes, lança o erro acima. No banco de dados, vejo tabelas de junção autogeradas (MenuDiets e RecipeDiets) e todos os dados parecem corretos. Novamente, como nos exemplos acima, posso consultar os dados, mas não posso incluir várias entidades relacionadas sem gerar o erro.
Se eu alterar a última consulta para usar apenas uma única inclusão, posso carregar a outra tabela sem problemas:
var dietsWithMenusAndRecipes = context.Diets
.Include(e => e.Menus).ToList();
foreach (var item in dietsWithMenusAndRecipes) {
context.Entry(item).Collection(e => e.Recipes).Load();
var rec = item.Recipes;
}
Além disso - embora isso não satisfaça meu caso de uso, pois quero restringir a tabela apenas aos valores enum e restrições exclusivas não são suportadas no EF - isso funcionará se eu alterar a classe de entidade Diet para usar uma chave de identidade separada, em vez que a tecla Enum:
public int Id { get; set; }
public DietIs DietIs { get; set; }
Outra solução possível que explorei foi criar explicitamente as tabelas de junção (MenuDiets e RecipeDiets) para que a chave de propriedade de junção fosse digitada como Enum, mas isso ainda retornava o erro acima.
Parece ser o múltiplo Includes que está causando um estrangulamento. Alguma idéia de se estou fazendo algo errado na configuração do modelo? A consulta em si? Um bug no Entity Framework?