2012-08-31 12 views
25

ठीक है, यह थोड़ा लंबा/अस्पष्ट है, लेकिन मुझे विशिष्ट स्थिति में एक अजीब त्रुटि मिल रही है जहां मैं एक टेबल कुंजी के रूप में एनम का उपयोग करता हूं और प्रयास करता हूं तालिका के खिलाफ पूछताछ करते हुए एक से अधिक संबंधित इकाइयों को शामिल करते हुए।इकाई फ्रेमवर्क में कुंजी के रूप में एनम 0 कई लोगों को कई फेंकने में त्रुटि

त्रुटि, नीचे दिए गए उदाहरण कोड से है:

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 वेब परियोजना में, मैं निम्नलिखित इकाई विन्यास है:

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

अन्य प्रश्न जहां मैं एक एकल का उपयोग करता हूं, बिना किसी समस्या के अपेक्षित डेटा लोड करता है। ऊपर दी गई क्वेरी में, दो के साथ उपरोक्त त्रुटि फेंकता है। डेटाबेस में मैं स्वत: जेनरेटेड टेबल (मेनूडिएट्स और रेसिपीडिएट्स) देखता हूं और सभी डेटा सही दिखते हैं। दोबारा, ऊपर दिए गए उदाहरणों में मैं डेटा के खिलाफ पूछताछ कर सकता हूं लेकिन त्रुटि को फेंकने के बिना कई संबंधित इकाइयों को शामिल नहीं कर सकता।

अगर मैं पिछले क्वेरी को परिवर्तित केवल एक ही शामिल हैं उपयोग करने के लिए, मैं इस मुद्दे के बिना अन्य तालिका लोड कर सकते हैं:

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

इसके अलावा - हालांकि यह मेरा उपयोग के मामले संतुष्ट नहीं करता के रूप में मैं मेज प्रतिबंधित करना चाहते हैं

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

एक अन्य संभावित समाधान मैं का पता लगाया: - करने के लिए सिर्फ enum मूल्यों और अद्वितीय की कमी एफई में समर्थित नहीं हैं इस अगर मैं एक अलग पहचान कुंजी का उपयोग करने आहार इकाई वर्ग बदलने के लिए, बल्कि enum कुंजी से काम करेंगे स्पष्ट रूप से शामिल टेबल (मेनूडिट) बनाना था एस और पकाने की विधि) ताकि शामिल संपत्ति कुंजी को एनम के रूप में टाइप किया गया हो, लेकिन यह अभी भी उपरोक्त त्रुटि को वापस कर दिया गया है।

यह वास्तव में कई शामिल हैं जो इसे चकित कर रहे हैं। मॉडल सेटअप में कुछ गलत कर रहा है या नहीं, इसके बारे में कोई विचार? सवाल खुद ही? इकाई फ्रेमवर्क में एक बग?

+0

क्यों आहार के पी DietIs के प्रकार है? क्रॉस-रेफरेंस टेबल आहार नहीं है? – zsong

+0

ठीक है, इस उदाहरण में, मैं विशेष आहार के बारे में कुछ जानकारी जोड़ना चाहता हूं, वेगन का वर्णन करें, ग्लूटेन-फ्री का वर्णन करें। मैं कोड में उपयोग किए गए एनम के संभावित मूल्यों को भी प्रतिबंधित करना चाहता हूं, और मैं भी एक int से आगे और पीछे कास्ट करना नहीं चाहता। –

+0

लेकिन उस आहार वस्तु का पीके सिर्फ एक नियमित पूर्णांक होना चाहिए। और मुझे लगता है कि आप FluentAPI का उपयोग कर विदेशी कुंजी रिश्ते को परिभाषित करते हैं। – zsong

उत्तर

5

यह मुद्दा यह तथ्य प्रतीत होता है कि enum .NET में एक वर्ग प्रकार है। this page पर परिभाषा से:

गणना के लिए आधार वर्ग प्रदान करता है।

और इस टिप्पणी:

एक गणन नामित स्थिरांक जिसका अंतर्निहित प्रकार किसी भी अभिन्न प्रकार है का एक सेट है। यदि कोई अंतर्निहित प्रकार स्पष्ट रूप से घोषित नहीं किया गया है, तो Int32 का उपयोग किया जाता है। एनईएम फ्रेमवर्क में सभी गणनाओं के लिए एनम बेस क्लास है।

हाँ, यह स्थिरांक जिसका प्रकार एक अभिन्न प्रकार है लेकिन जब आप yor कुंजी की घोषणा का एक सेट को परिभाषित करता है:

public DietIs DietIs { get; set; } 

आपका कुंजी वास्तव में एक वर्ग प्रकार एक अभिन्न प्रकार नहीं है; अभिन्न प्रकार के मानों की तुलना या असाइन करते समय आपको इसे कास्ट करना पड़ सकता है। पेज रूपांतरण के बारे में इस उदाहरण प्रदान करता है:

आप एक गणन सदस्य और एक कास्टिंग या रूपांतरण (सी # में) (विजुअल बेसिक में) ऑपरेटर का उपयोग करके उसके अंतर्निहित प्रकार के बीच में बदल सकते हैं। निम्नलिखित उदाहरण रूपांतरणों को एक पूर्णांक से एक गणना मूल्य से और गणना मूल्य से पूर्णांक तक करने के लिए आवरण या रूपांतरण ऑपरेटरों का उपयोग करता है।

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


int value3 = 2; 
ArrivalStatus status3 = (ArrivalStatus) value3; 
int value4 = (int) status3; 
संबंधित मुद्दे