why the explicit load does not work,and the navigation property always null?

All my code is here,quite simple,and I don't konw where it goes wrong.

Person and Task has an many-to-many relationship. I want to load someone's task using the explicit way. I follow the way this post shows,and i can't make it work.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Task> Tasks { get; set; }
}
public class Task
{
    public int Id { get; set; }
    public string Subject { get; set; }
    public ICollection<Person> Persons { get; set; }

}

public class Ctx : DbContext
{
    public Ctx()
        : base("test")
    {
        this.Configuration.LazyLoadingEnabled = false;
        this.Configuration.ProxyCreationEnabled = false;
    }
    public DbSet<Person> Persons { get; set; }
    public DbSet<Task> Task { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        //add some data as follows
        //using (var ctx = new Ctx())
        //{

            //ctx.Persons.Add(new Person { Name = "haha" });
            //ctx.Persons.Add(new Person { Name = "eeee" });

            //ctx.Task.Add(new Task { Subject = "t1" });
            //ctx.Task.Add(new Task { Subject = "t2" });
            //ctx.SaveChanges();

            //var p11 = ctx.Persons.FirstOrDefault();
            //ctx.Task.Include(p2 => p2.Persons).FirstOrDefault().Persons.Add(p11);
            //ctx.SaveChanges();
        //}

        var context = new Ctx();
        var p = context.Persons.FirstOrDefault();

        context.Entry(p)
        .Collection(p1 => p1.Tasks)
        .Query()
        //.Where(t => t.Subject.StartsWith("t"))
        .Load();

        //the tasks should have been loaded,isn't it?but no...
        Console.WriteLine(p.Tasks != null);//False

        Console.Read();
    }
}

Is there anything wrong with my code?I'm really new to EF,so please, someone help me.

Answers


The problem is your .Query() call. Instead of loading the collection, you are getting a copy of the IQueryable that would be used to load, then executing the query.

Remove your .Query() line and it will work.


If what you are looking for is getting a filtered list of collection elements, you can do this:

var filteredTasks = context.Entry(p)
                           .Collection(p1 => p1.Tasks)
                           .Query()
                           .Where(t => t.Subject.StartsWith("t"))
                           .ToList();

This will not set p.Tasks, nor is it a good idea to do so, because you'd be corrupting the domain model.

If you really, really want to do that... this might do the trick (untested):

var collectionEntry = context.Entry(p).Collection(p1 => p1.Tasks);
collectionEntry.CurrentValue =
    collectionEntry.Query()
                   .Where(t => t.Subject.StartsWith("t"))
                   .ToList();

This solution worked for me :

For some reasons EF requires virtual keyword on navigation property, so the entities should be like this :

public class Person
{
    //...
    public virtual ICollection<Task> Tasks { get; set; }
}

public class Task
{
    //...
    public virtual ICollection<Person> Persons { get; set; }

}

Need Your Help

iframe not working in tinymce when valid_elements defined

javascript tinymce tinymce-4 tinymce-3

As soon as I define any valid_elements and/or extended_valid_elements I cannot insert iframe (iframe defined among valid_elements, extended_valid_elements)

mysql - sql query multiple tables

php mysql sql

I have a database in 2 versions: 25-7-2015 let's call it db1 and 5-8-2015 let's call it db2.