枚举在实体框架5投掷的错误主要在多对多连接(Enum as Key in entity framew

2019-07-31 07:38发布

OK,这是一个有点冗长/晦涩难懂,但我在我使用枚举作为一个表密钥和尝试查询对阵表,而其中超过一个多到许多相关实体的具体情况得到一个奇怪的错误。

误差,从下面的例子中的代码是:

The type of the key field 'DietIs' is expected to be 'MvcApplication8.Models.DietIs', but the value provided is actually of type 'System.Int32'.

在.NET 4.5 Web项目,我有以下实体配置:

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;
    }
}

在文件的Global.asax.cs我初始化数据库:

 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();
        }

于是,我尝试查询针对数据库:

var context = new EnumTestContext();

        var dietsWithMenusAndRecipes = context.Diets
                  .Include(e => e.Menus)
                  .Include(e => e.Recipes)
                  .ToList();

这里我用一个单一的其他查询包括加载预期的数据没有问题。 上面的查询,有两个包含抛出上述错误。 在我看到自动生成的数据库连接表(MenuDiets和RecipeDiets)和所有的数据看起来是正确的。 同样,在上面的例子中我就可以查询数据,但不能包括多个相关的实体,而不引发错误。

如果我改变的最后一个查询只使用一个单一的包括,我可以加载没有问题,其他表:

        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;
        }

另外 - 尽管这不符合我的使用情况下,我想限制表只枚举值和唯一约束在EF不支持 - 如果我改变饮食实体类使用一个单独的身份密钥,这将工作,而比Enum项:

    public int Id { get; set; }
    public DietIs DietIs { get; set; }

另一种可能的解决方案我探索是明确创建的连接表(MenuDiets和RecipeDiets),使联接属性密钥类型为枚举,但仍返回上面的错误。

这真的好像是多个包括正在导致其窒息。 任何想法,我是否做错了模型中的设置? 查询本身? 实体框架中的错误吗?

Answer 1:

这个问题似乎是一个事实,即enum在.NET是一个类类型。 从定义本页面 :

提供枚举的基类。

而这句话:

枚举是一组命名的常量,其基础类型为任何整数类型。 如果没有基本类型是明确声明,使用的Int32。 ENUM是在.NET框架中所有枚举的基类。

是的,它定义了一组常量,其类型为一个整数类型,但在声明侑关键的:

public DietIs DietIs { get; set; }

您的密钥实际上是一个类类型不是一个整数类型; 你可能有比较或指定整型值时,将其强制转换。 该页面提供了有关转换这个例子:

可以枚举成员并通过使用铸造(在C#)或转化(在Visual Basic)算其底层类型之间进行转换。 下面的示例使用套管或转换操作符既从整数到枚举值以及从一个枚举值的整数执行转换。

public enum ArrivalStatus { Late=-1, OnTime=0, Early=1 };


int value3 = 2;
ArrivalStatus status3 = (ArrivalStatus) value3;
int value4 = (int) status3;


文章来源: Enum as Key in entity framework 5 throwing error on many to many joins