Saturday, July 23, 2005

[Opf3] Question: Create one-to-many relations

Christian,

We are evaluating your product here at our company and have a question on WeakPersistent relationships. I have successfuly created a many-to-many WeakPersistent relationship such that removing a mapped object from the ObjectSet of the other does not delete it from the database. However, I am stuck on how to do the same for a one-to-many relationship. Such a relationship has no mapping table in the storage so I cannot create a matching class in the code. What am I missing here?

Thanx
Jay


Answer:
Hi Jay, you don't need any mapping class in a 1:n relationship. It is rather simple to create that one:


[Peristent("FOO")]
public class Foo
{
    private int _id;
    private string _name;

    // Create an ObjectSetHolder of Bar to connect with
    // Bar objects. The relation connects the property "ID"
    // of this class with the "FooID" property of the
    // related objects.
    [Relation("ID = FooID")]
    private ObjectSetHolder<Bar> _bars = new ObjectSetHolder<Bar>();

    public ObjectSet Bars
    {
       get { return _bars.InnerObject; }
    }

    [Field("ID", AllowDBNull = false, Identifier = true, AutoNumber = true)]
    public int ID
    {
        get { return _id; }
        private set { _id = value; }
    }

    [Field("NAME", AllowDBNull = false)]
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

public class Bar
{
    private int _id;
    private string _text;
    private int _fooID;

    [Field("ID", AllowDBNull = false, Identifier = true, AutoNumber = true)]
    public int ID
    {
        get { return _id; }
        private set { _id = value; }
    }

    [Field("FOO_ID", AllowDBNull = false)]
    public string FooID
    {
        get { return _fooID; }
        set { _fooID = value; }
    }

    [Field("TEXT", AllowDBNull = false)]
    public string Text
    {
        get { return _text; }
        set { _text = value; }
    }
}


As you see you have only to create (in the class that should then contain the list of related objects) an ObjectSetHolder and decorate that class with a RelationAttribute. The first argument of the RelationAttribute's constructor is the property of the single object in the 1:n relation. The second argument is the property of the n objects (the property that is mapped to the foreign key in the database) in the 1:n relation.

You could have a look at the "Relations" sample that is part of the "tutorial and samples" from the Opf3 homepage. That sample contains a one-to-many relation.

If you delete a related object in a one-to-many or one-to-one relation that related object is deleted when you save the "parent" object. Example:


// Load a foo object from the storage.
Foo foo = context.GetObject("ID = 1");
// Delete the first object.
foo.Bars.RemoveAt(0);

// Save the instance of Foo.
// The removed instance of Bar is deleted form the storage.
// In a one-to-many and one-to-one relation related objects
// are deleted from the storage if they are removed.
context.PersistChanges(foo);


In a many-to-many relation the related object isn't deleted because because it may be still connected with another item in the database.

I hope I could help you with this post. If you (or anybody else) has any further question don't hesitate to post them here as comments

2 Comments:

Anonymous Anonymous said...

>If you delete a related object in a
>one-to-many or one-to-one relation
>that related object is deleted when
>you save the "parent" object.

Christian, thank you for your response. I understand what you have written and was able to do that successfully. However, my question, was how to keep OPF3 from deleting the dependant object's record in storage. I want to create a WeakPersistent relationship like in a many-to-many mapping but for a one-to-many or one-to-one mapping.

7/25/2005 3:24 PM  
Blogger Christian said...

Hi Jay,

If you remove a persistent from an ObjectSet it is moved to the RemovedList (see the RemovedList property of the ObjectSet). If you remove it from that list it is not deleted from the database.

I hope this helps you?!

7/26/2005 11:01 AM  

Post a Comment

<< Home