2

This is the code which I'm not convinced. Please check how I'm passing as parameter the entity Collection.

public ExamProduced GetExamProduced(XElement xml)
{
    var examProduced = new ExamProduced
    {
        ExamProducedID = (int)xml.Attribute("ExamID"),
        Date = (DateTime)xml.Attribute("Date"),
        Seed = (int)xml.Attribute("Seed"),
        //Exercises = GetExercises(xml)
    };

    GetExercises(xml, examProduced.Exercises);
    return examProduced;
}

public void GetExercises(XElement xml, EntityCollection<Exercise> entityCollection)
{
    var objs =
        from objective in xml.Descendants("Objective")
        where (bool)objective.Attribute("Produced")
        let id = (int)objective.Attribute("ID")
        let id2 = (Objective)entityService.Objectives.Where(o => o.ObjectiveID == id).FirstOrDefault()
        select new Exercise
        {
            Objective = id2,
            MakeUp = ...
            Quantify = ...
            Score = ...
        };

    foreach (var exercise in objs)
    {
        entityCollection.Add(exercise);
    }
}

If not, I'll receiving an error. Like this with this code.

public ExamProduced GetExamProduced(XElement xml) 
{ 
    var examProduced = new ExamProduced 
    { 
        ExamProducedID = (int)xml.Attribute("ExamID"), 
        Date = (DateTime)xml.Attribute("Date"), 
        Seed = (int)xml.Attribute("Seed"), 
        Exercises = GetExercises(xml) 
    }; 

    return examProduced; 
} 

public EntityCollection<Exercise> GetExercises(XElement xml) 
{ 
    var objs = 
        from objective in xml.Descendants("Objective") 
        where (bool)objective.Attribute("Produced") 
        let id = (int)objective.Attribute("ID") 
        select new Exercise 
        { 
            ExerciseID = id, 
            MakeUp = (bool)objective.Attribute("MakeUp"), 
            Quantify = (byte)(int)objective.Attribute("Quantify"), 
            Score = (float)objective.Elements().Last().Attribute("Result") 
        }; 

        var entityCollection = new EntityCollection<Exercise>();

        foreach (var exercise in objs)
            entityCollection.Add(exercise);

        return entityCollection;
} 

enter image description here

The error I am getting is below:

InvalidOperationException was unhandled.

The object could not be added to the EntityCollection or EntityReference. An object that is attached to an ObjectContext cannot be added to an EntityCollection or EntityReference that is not associated with a source object.

Otiel
  • 18,404
  • 16
  • 78
  • 126
Darf
  • 2,495
  • 5
  • 26
  • 37
  • Unfortunately I can't see the image. What is the error you're receiving? – Phil Klein Dec 16 '11 at 23:56
  • InvalidOperationException was unhandled. The object could not be added tot he EntityCollection or EntityReference. An object that is attached to an ObjectContext cannot be added to an EntityCollection or EntityReference that is not associated with a source object. – William Melani Dec 17 '11 at 00:06
  • Why do you need an `EntityCollection` of `Exercise` objects? Why not just use a `List`? – Yakimych Dec 17 '11 at 00:42
  • Because I'm using a database with Entity Framework – Darf Dec 17 '11 at 01:46
  • That really doesn't answer the question. An `EntityCollection` isn't just a list of objects that happen to have a common context, it's exclusively for a detail navigation property of a master object. What you're trying to use it for isn't what it's made for. I agree with Yakimych, just use a `List` -- specifically: a `List`. –  Dec 18 '11 at 01:13
  • hvd, can you put me an example please. I can't figure the solution – Darf Dec 18 '11 at 05:01
  • @OscarFimbres I've posted an answer based on my current understanding of your question; it's possible I'm missing the point entirely. Please let me know if it helps. –  Dec 18 '11 at 19:21

1 Answers1

0

I hope that from the comments I'm understanding you correctly... If not, I'll update this answer.

Firstly, your EntityCollection<Exercise> GetExercises(XElement xml) is not going to work. As the error message says, you cannot construct a random EntityCollection like that: the EntityCollection needs the object to be attached to the context because it automatically synchronises its list with the context. And since you aren't saying what to attach it to anywhere, it won't work. The only way to make it work would be to avoid creating an EntityCollection in the first place.

Your void GetExercises(XElement xml, EntityCollection<Exercise> entityCollection) procedure could work. However, you need to make sure to actually have an EntityCollection<Exercise> instance to be able to call it. The way you're creating your ExamProduced object, it isn't attached to the context by the time you return from GetExamProduced, so it isn't possible to have a EntityCollection<Exercise> property for it at that point.

Perhaps the easiest way to get things working would be to pass your context to the GetExamProduced method, and let them get attached to the context automatically. I'm assuming it's a common ObjectContext, but you can update it as needed:

public ExamProduced GetExamProduced(XElement xml, YourContext context)
{
    var examProduced = new ExamProduced()
    {
        ExamProducedID = (int)xml.Attribute("ExamID"),
        Date = (DateTime)xml.Attribute("Date"),
        Seed = (int)xml.Attribute("Seed")
    };
    context.ExamsProduced.Attach(examProduced);
    LoadExercises(xml, context, examProduced);
    // examProduced.Exercises should be available at this point
    return examProduced;
}

public void LoadExercises(XElement xml, YourContext context, ExamProduced examProduced)
{
    foreach (var exercise in
        from objective in xml.Descendants("Objective")
        where (bool)objective.Attribute("Produced")
        let id = (int)objective.Attribute("ID")
        let id2 = (Objective)entityService.Objectives.Where(o => o.ObjectiveID == id).FirstOrDefault()
        select new Exercise
        {
            ExamProduced = examProduced,
            Objective = id2,
            MakeUp = ...
            Quantify = ...
            Score = ...
        }))
    {
        context.Exercises.Attach(exercise);
    }
}

I don't know if these are new objects that should be added in the database, or if these objects are expected to exist in the database already. I've assumed the latter. If the former, .Attach should be updated to .AddObject in two places.

Is this what you're looking for, or did I misunderstand?

  • Yeah, that's it what I was looking for. Attach() is not working for me, it fixed by Add(). If I use Attach function, it produces an exeption like this: Attach is not a valid operation when the source object associated with this related end is in an added, deleted, or detached state. Objects loaded using the NoTracking merge option are always detached. – Darf Dec 19 '11 at 17:57
  • That suggests you're calling `examProduced.Exercises.Attach` rather than `context.Exercises.Attach`, but the way you're doing it should also work. –  Dec 19 '11 at 18:07