7

मैं SQL सर्वर 2012 डेटाबेस के विरुद्ध DbContext POCO दृष्टिकोण का उपयोग कर इकाई फ्रेमवर्क 4.3.1 का उपयोग कर रहा हूं।एक समय-समय पर नेविगेशन प्रॉपर्टी को लोड होने से क्यों रोकें?

मैं डेटाबेस में सिर्फ दो टेबल है और वे इस तरह दिखेगा:

tables

नोट: कोई विदेशी बिल्कुल डेटाबेस में निर्दिष्ट की गई कुंजियों रहे हैं - मैं केवल इन रिलेशनशिप को लागू कर रहा हूँ मॉडल (मैं डेटाबेस नहीं बदल सकता)।

वे एक उन में डेटा की एक पंक्ति है कि इस तरह दिखता है: अब

validation

:

data

मैं में शामिल होने के लिए काम करेंगे सुनिश्चित करने के लिए निम्न क्वेरी प्रदर्शन किया , मेरे पास निम्नलिखित संस्थाएं हैं:

public class Two 
{ 
    public long TwoId { get; set; } 
    public string OneId { get; set; } 
    public virtual One One { get; set; } 
} 

public class One 
{ 
    public string OneId { get; set; } 
    public DateTime DeliveryDate { get; set; } 
    public virtual ICollection<Two> Twos { get; private set; } 

    public void AddTwo(Two two) 
    { 
     if (two == null) 
      throw new ArgumentNullException("two"); 

     if (Twos == null) 
      Twos = new List<Two>(); 

     if (!Twos.Contains(two)) 
      Twos.Add(two); 

     two.One = this; 
    } 
} 

और इस संदर्भ है: जब मैं कोड के इस बिट मैं अपने कंसोल के लिए मुद्रित Why is this printed? मिल चलाने

public class TestContext : DbContext 
{ 
    public TestContext(string conectionString) 
     : base(conectionString) 
    { 
     Configuration.LazyLoadingEnabled = true; 
     Ones = Set<One>(); 
     Twos = Set<Two>(); 
    } 
    public DbSet<One> Ones { get; private set; } 
    public DbSet<Two> Twos { get; private set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     var one = modelBuilder.Entity<One>(); 
     one.ToTable("One"); 
     one.HasKey(d => d.OneId); 

     var two = modelBuilder.Entity<Two>(); 
     two.ToTable("Two"); 
     two.HasKey(d => new 
          { 
           d.OneId, 
           d.TwoId 
          }); 
     two.Property(p => p.TwoId) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 
     two.HasRequired(t => t.One) 
      .WithMany(o => o.Twos) 
      .HasForeignKey(o => o.OneId); 
     base.OnModelCreating(modelBuilder); 
    } 
} 

- जो मैं के रूप में आप देख सकते हैं कि नेविगेशन संपत्ति (मैं में भरा जाना चाहिए की उम्मीद नहीं है यहां तक ​​कि स्पष्ट रूप से इसे शामिल है):

using (var ctx = new TestContext(@"......")) 
{ 
    const string oneId = "111348718"; 
    var one = ctx.Ones.Single(o => o.OneId.Equals(oneId)); 

    if (one != null) 
    { 
     var sdi = ctx 
      .Twos 
      .Include(s => s.One) 
      .Single(s => s.OneId.Equals(oneId)); 

     if (sdi.One == null) 
     { 
      Console.WriteLine("Why is this printed?"); 
     } 
     else 
     { 
      Console.WriteLine("This is what I expect"); 
     } 
    } 
} 

अब, यह वास्तव में अजीब सा है: यदि मैं बस One वर्ग यह ठीक काम करता है से DeliveryDate संपत्ति बाहर टिप्पणी (मैं This is what I expect मुद्रित टी मिल ओ कंसोल)।

यहां क्या गलत है और मैं इसे कैसे हल कर सकता हूं?

नोट: अगर मैं one चर इसे सही ढंग से उम्मीद मान पर सेट कर दिया गया है पर DeliveryDate संपत्ति को देखो तो तारीख डेटाबेस में ठीक होना चाहिए और इकाई की रूपरेखा पूरी तरह से यह अमल में लाना करने में सक्षम है।

अधिक जानकारी: तथ्य यह है कि यह एक तारीख है बात नहीं है - अगर ऐसा है, का कहना है कि एक nvarchar यह अभी भी विफल रहता है - किसी भी सरल संपत्ति पर गिर पूरी बात का कारण बनता है लगता है - यह करने के लिए एक बग की तरह लगता है मुझे ...

उत्तर

2

ठीक है, इसलिए मुझे इसके नीचे जाना है और मुझे लगता है कि यह इकाई फ्रेमवर्क में एक बग है, लेकिन मैं इसके आसपास काम कर सकता हूं। यहां यह है कि यह है ...

दो टेबल में वनआईड कॉलम अंत में एक ही स्थान था।

युप - आंकड़ा - यह कितना बुरा है !?

इसलिए मैंने एक एसक्यूएल स्क्रिप्ट को खारिज कर दिया जिसने डेटाबेस में प्रत्येक nvarchar कॉलम पर LTRIM(RTRIM( किया और सभी ठीक काम कर रहे हैं।

अब, एसक्यूएल सर्वर को रिक्त स्थान की परवाह नहीं है (जैसा कि प्रश्न में शामिल होने के साथ क्वेरी द्वारा सिद्ध किया गया है) मुझे वास्तव में यह पसंद नहीं है कि इकाई फ्रेमवर्क परवाह है, खासकर क्योंकि यह पूरी तरह से अजीब और असंगत है। निश्चित रूप से वह बिंदु जहां मैं Single को sdi प्राप्त करने के लिए कॉल करता हूं, चरम आबादी को फेंक दिया जाना चाहिए था या नेविगेशन संपत्ति को पॉप्युलेट किया जाना चाहिए था - एक या दूसरा लेकिन यह व्यवहार वास्तव में वास्तव में भ्रमित है (मेरी राय में) - कुछ मनमानी संपत्ति को क्या करना है मछली की कीमत के साथ ??

बस पूर्णता के लिए यहां वास्तव में इसे पुन: उत्पन्न करने के लिए कुछ है। एक नया डेटाबेस बनाने और फिर उस पर इस SQL ​​स्क्रिप्ट चलाएँ:

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [dbo].[One](
    [OneId] [nvarchar](10) NOT NULL, 
    [SomeInt] [int] NOT NULL, 
CONSTRAINT [PK_Delivery] PRIMARY KEY CLUSTERED 
(
    [OneId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

CREATE TABLE [dbo].[Two](
    [TwoId] [int] NOT NULL, 
    [OneId] [nvarchar](10) NOT NULL, 
CONSTRAINT [PK_DeliveryItem] PRIMARY KEY CLUSTERED 
(
    [TwoId] ASC, 
    [OneId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

INSERT INTO Two(TwoId, OneId) VALUES (1, '1 ') 
INSERT INTO One(OneId, SomeInt) VALUES ('1', 1.0) 

अब एसी # सांत्वना आवेदन बनाने के लिए, EntityFramework (संस्करण 4.3.1) और System.Data.Entity के लिए एक संदर्भ जोड़ने असेंबली, इस कोड को इसमें डाल दें और चलाएं - यह SHOULD NOT BE PRINTED!!! प्रिंट करेगा। One वर्ग

  • डेटाबेस (UPDATE Two SET OneId = RTRIM(OneId)) में अंतरिक्ष बंद ट्रिम पर SomeInt संपत्ति बाहर

    • टिप्पणी:

      using System; 
      using System.Collections.Generic; 
      using System.ComponentModel.DataAnnotations; 
      using System.Data.Entity; 
      using System.Linq; 
      
      namespace EFTest 
      { 
          public class Two 
          { 
           public int TwoId { get; set; } 
           public string OneId { get; set; } 
           public virtual One One { get; set; } 
          } 
      
          public class One 
          { 
           public string OneId { get; set; } 
           public virtual ICollection<Two> Twos { get; private set; } 
      
           // Comment out this property and it will work 
           public int SomeInt { get; set; } 
      
           public void AddTwo(Two two) 
           { 
            if (two == null) 
             throw new ArgumentNullException("two"); 
      
            if (Twos == null) 
             Twos = new List<Two>(); 
      
            if (!Twos.Contains(two)) 
             Twos.Add(two); 
      
            two.One = this; 
           } 
          } 
      
          public class Context : DbContext 
          { 
           public Context(string connectionString) 
            : base(connectionString) 
           { 
            Configuration.LazyLoadingEnabled = true; 
            Ones = Set<One>(); 
            Twos = Set<Two>(); 
           } 
      
           public DbSet<One> Ones { get; private set; } 
           public DbSet<Two> Twos { get; private set; } 
      
           protected override void OnModelCreating(DbModelBuilder modelBuilder) 
           { 
            modelBuilder 
             .Entity<One>() 
             .HasKey(d => d.OneId) 
             .ToTable("One"); 
      
            var two = modelBuilder.Entity<Two>(); 
            two.ToTable("Two"); 
            two.HasKey(d => new 
                 { 
                  d.OneId, 
                  d.TwoId 
                 }); 
      
            two.Property(d => d.TwoId) 
             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 
      
            two.HasRequired(m => m.One) 
             .WithMany(t => t.Twos) 
             .HasForeignKey(d => d.OneId); 
      
            base.OnModelCreating(modelBuilder); 
           } 
          } 
      
          internal class Program 
          { 
           private static void Main() 
           { 
            using (var ctx = new Context(@"your connection string")) 
            { 
             const string oneId = "1"; 
             var one = ctx.Ones.Single(o => o.OneId.Equals(oneId)); 
      
             if (one == null) 
             { 
              Console.WriteLine("No row with one ID in the database"); 
              return; 
             } 
      
             var two = ctx 
              .Twos 
              .Include(s => s.One) 
              .Single(s => s.OneId.Equals(oneId)); 
      
             Console.WriteLine(two.One == null 
                   ? "SHOULD NOT BE PRINTED!!!" 
                   : "SHOULD BE PRINTED"); 
            } 
           } 
          } 
      } 
      

      तो इनमें से किसी एक से करते हैं।

    या तो काम करेगा (जाहिर है कि ट्रिमिंग ही एकमात्र उचित वास्तविक जीवन तय है)।