English 中文(简体)
Convince entity context (EF1) to populate entity references
原标题:

I have an entity with self reference (generated by Entity Designer):

public MyEntity: EntityObject
{
    // only relevant stuff here
    public int Id { get...; set...; }
    public MyEntity Parent { get...; set...; }
    public EntityCollection<MyEntity> Children { get...; set...; }
    ...
}

I ve written a stored procedure that returns a subtree of nodes (not just immediate children) from the table and returns a list of MyEntity objects. I m using a stored proc to avoid lazy loading of an arbitrary deep tree. This way I get relevant subtree nodes back from the DB in a single call.

List<MyEntity> nodes = context.GetSubtree(rootId).ToList();

All fine. But when I check nodes[0].Children, its Count equals to 0. But if I debug and check context.MyEntities.Results view, Children enumerations get populated. Checking my result reveals children under my node[0].

How can I programaticaly force my entity context to do in-memory magic and put correct references on Parent and Children properties?

UPDATE 1

I ve tried calling

context.Refresh(ClientWins, nodes);

after my GetSubtree() call which does set relations properly, but fetches same nodes again from the DB. It s still just a workaround. But better than getting the whole set with context.MyEntities().ToList().

UPDATE 2

I ve reliably solved this by using EF Extensions project. Check my answer below.

最佳回答

The REAL solution

Based on this article (read text under The problem), navigation properties are obviously not populated/updated when one uses stored procedures to return data.

But there s a nice manual solution to this. Use EF Extensions project and write your own entity Materilizer<EntityType> where you can correctly set navigation properties like this:

...
ParentReference = {
    EntityKey = new EntityKey(
        "EntityContextName.ParentEntitySetname",
        new[] {
            new EntityKeyMember(
                "ParentEntityIdPropertyName",
                reader.Field<int>("FKNameFromSP")
            )
        })
}
...

And that s it. Calling stored procedure will return correct data, and entity object instances will be correctly related to eachother. I advise you check EF Extensions samples, where you will find lots of nice things.

问题回答

You need to assign one end of the relationship. First, divide the collection:

var root = nodes.Where(n => n.Id == rootId).First();
var children = nodes.Where(n => n.Id != rootId);

Now, fix up the relationship.

In your case, you d do either:

foreach (var c in children)
{
    c.Parent = root;
}

...or:

foreach (var c in children)
{
    root.Children.Add(c);
}

It doesn t matter which.

Note that this marks the entities as modfied. You ll need to change that if you intend to call SaveChanges on the context and don t want this saved.





相关问题
Entity Framework with MySQL connector in c#

I have been trying to get the Entity Framework to work in my web application using MySQL. It works fine on my local pc, but doesn t work when I put it on the server. Since the server is a shared ...

How Do I Create And Update A Many To Many Relationship With EF

I am using the Entity Framework with SQL Server. I have a many to many relationship between 2 tables. I have created a join table with just the primary key fields of the 2 tables. In the designer, the ...

Entity Framework with File-Based Database

I am in the process of developing a desktop application that needs a database. The application is currently targeted to SQL Express 2005 and works wonderfully. However, I m not crazy about having ...

Linq to enties, insert foreign keys

I am using the ADO entity framework for the first time and am not sure of the best way of inserting db recored that contain foreign keys. this is the code that i am using, I would appreciate any ...

Entity Framework - Many to many question

I have a table called ASB and a table called PeopleInvolved. There is a junction table called PeopleInvolved_ASB which simply contains an ASBID and a PeopleInvolvedID column. The columns act as a ...

Post back complex object from client side

I m using ASP.NET MVC and Entity Framework. I m going to pass a complex entity to the client side and allow the user to modify it, and post it back to the controller. But I don t know how to do that ...

ADO.NET Entity Data Model are not precise enough

I run this code: var cos = from k in _db.klienci_do_trasy where k.klient_id == 5 select k; but the query send to database is: SELECT * FROM `klienci_do_trasy` LIMIT 0, 30 why is it for, there ...

热门标签