OK, esto es un poco largo/oscuro, pero me da un error extraño en una situación específica donde uso un Enum como clave de tabla e intento de consulta contra la tabla al tiempo que incluye más de una entidad relacionada de muchos a muchos.Enum como clave en el marco de la entidad 5 error de lanzamiento en muchas combinaciones
El error, desde el código de ejemplo a continuación es:
The type of the key field 'DietIs' is expected to be 'MvcApplication8.Models.DietIs', but the value provided is actually of type 'System.Int32'.
En un proyecto web .NET 4.5, I tienen la siguiente configuración entidad:
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;
}
}
En el Global.asax.cs solicito inicializar la base de datos:
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();
}
Entonces, trato de consulta en la base de datos:
var context = new EnumTestContext();
var dietsWithMenusAndRecipes = context.Diets
.Include(e => e.Menus)
.Include(e => e.Recipes)
.ToList();
Otras consultas donde utilizo una sola incluyen cargar los datos esperados sin problema. La consulta anterior, con dos incluye arroja el error anterior. En la base de datos veo tablas de combinación autogeneradas (MenuDiets y RecipeDiets) y todos los datos parecen correctos. De nuevo, como en los ejemplos anteriores, puedo consultar los datos pero no puedo incluir varias entidades relacionadas sin arrojar el error.
Si cambio de la última consulta para utilizar solamente un solo incluyen, puedo cargar la otra mesa sin ningún problema:
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;
}
adicional - aunque esto no satisface mi caso de uso como quiero para restringir la mesa sólo a los valores de enumeración y restricciones únicas no son compatibles con EF - esto funcionará si cambio de la clase de entidad dieta utilizar una clave de identidad separada, en lugar de la clave de enumeración:
public int Id { get; set; }
public DietIs DietIs { get; set; }
Otra posible solución exploré era crear explícitamente las tablas de unión (MenuDiet s y RecipeDiets) para que la clave de propiedad join se haya tipeado como Enum, pero esto aún devuelve el error anterior.
Parece que realmente son las múltiples inclusiones las que provocan que se ahogue. ¿Alguna idea sobre si estoy haciendo algo mal en la configuración del modelo? La consulta en sí? ¿Un error en Entity Framework?
Por qué la FC de la dieta tienen el tipo de DietIs? ¿No es Diet la tabla de referencias cruzadas? – zsong
Bueno, en este ejemplo, quiero agregar algo de información sobre dietas particulares, por ejemplo, describo Vegan, describo Gluten-Free, etc. También quiero restringir los posibles valores a los de la enumeración que uso en el código, y también me pongo No quiero tener que lanzar hacia adelante y hacia atrás desde un int. –
Pero el PK de ese objeto de dieta debe ser simplemente un entero regular. Y supongo que definiste la relación de clave externa usando FluentAPI. – zsong