zeroc8
zeroc8

Reputation: 873

EF7 Read Master Detail Records

I'm trying to get my head around EF7 by writing a simple master-detail relationship to a sqlite database. Saving works fine, reading however gives me headaches:

Here are my Entities:

public class Message
{
    public int MessageId { get; set; }
    public string Name { get; set; }        
    public List<MessagePart> MessageParts { get; set; }
}
public class MessagePart
{
    public int MessagePartId { get; set; }
    public string Text { get; set; }        
    public int MessageId { get; set; }
    public Message Message { get; set; }
}

createMessage() does what it is supposed to:

static void createMessages()
    {
        using (var db = new TestContext())
        {
            var m1 = new Message
            {
                Name = "train_arrives_in_x_minutes",                    
                MessageParts = new List<MessagePart>()
                {
                    new MessagePart {
                        Text = "Train arrives in 5 minutes"                            
                    },
                    new MessagePart {
                        Text = "Zug faehrt in 5 Minuten ein",                            
                    }
                }
            };
            var m2 = new Message
            {
                Name = "train_out_of_service",
                MessageParts = new List<MessagePart>()
                {
                    new MessagePart {
                        Text = "train is out of service"                            
                    },
                    new MessagePart {
                        Text = "Kein Service auf dieser Strecke",                            
                    }
                }
            };

            db.Messages.Add(m1);
            db.Messages.Add(m2);

            var count = db.SaveChanges();
            Console.WriteLine("{0} records saved to database", count);

        }
    }

Reading from an existing database reads the master record fine, but the detail recordset pointer stays null.

static void readMessages()
    {
        using (var db = new TestContext())
        {
            foreach (Message m in db.Messages)
            {
                Console.WriteLine(m.Name);
                // exception here: m.MessageParts is always null
                foreach(MessagePart mp in m.MessageParts)
                {
                    Console.WriteLine("mp.Text={0}", mp.Text);
                }                    
            }                
        }
    }

Is there anything I can do to force those messagesparts to load? I've worked with other (Python) ORMs before and never had this problem before. Is this a problem with Lazy Loading? I tried to fetch those childrecords using a LINQ statement, that didn't help either. Everything looks good in the database though.

Upvotes: 1

Views: 228

Answers (1)

Adil Mammadov
Adil Mammadov

Reputation: 8696

If you want to enable LazyLoading you need to enable LazyLoading (should be enabled by default) and make your property virtual:

public TestContext() 
    : base(Name = "ConntextionName")
{
    this.Configuration.ProxyCreationEnabled = true;
    this.Configuration.LazyLoadingEnabled = true;
}

And your models shuodl look like:

public class Message
{
    public int MessageId { get; set; }
    public string Name { get; set; }        
    public virtual ICollection<MessagePart> MessageParts { get; set; }
}
public class MessagePart
{
    public int MessagePartId { get; set; }
    public string Text { get; set; }        
    public int MessageId { get; set; }
    public virtual Message Message { get; set; }
}

If you do not want to use LazyLoading, you can load related entities using eager loading:

using System.Data.Entity;

using (var db = new TestContext())
{
    int messageId = ....;
    Message message = db.Messages
        .Where(m => m.MessageId == messageId)
        .Include(m => m.MessageParts) // Eagerly load message parts
        .FirstOrDefault();

    // Your message and all related message parts are now loaded and ready.
}

For more information, please have a look at this site.

Upvotes: 2

Related Questions