Best way to mapping records into one part?

Topics: Writing modules
Sep 28, 2011 at 8:30 AM

Hello.
I have a question, is exist a posible way to map more then one Record into a single Part?


For example:
Default UserPartRecord contains: Id, UserName, Email, ...
MyUserPartRecord contains: Id, PhoneNumber, Salary, ...
That is the best way to map this records into ExtendedUserPart: Id, UserName, Email, ..., PhoneNumber, Salary, ... ?

The main task is: safe orchard mehanism to manage users and in own module have extended user with data manipulation from c# code (not just Fields in user shape).

Developer
Sep 28, 2011 at 9:30 AM

If I understand correctly, you want to have an own Part (with record) in your module that hooks together with UserPart (which means you really want to extend the User content type). This can be done by adding this to your handler:

Filters.Add(new ActivatingFilter<MyUserPart>("User"));

This makes it possible then to "cast" a UserPart to MyUserPart with the As() method of the content manager and vica versa, like:

_contentManager
                .Query<MyUserPart, MyUserPartRecord>()
                .Where(...).List().FirstOrDefault<MyUserPart>().As<UserPart>();

Where _contentManager is an IContentManager instance.

Sep 29, 2011 at 6:58 AM
Edited Sep 29, 2011 at 7:00 AM

Interesting, this is not exactly that I mean, but I will try to dig around the filters. Thanks

For now my ExtendedUserPartRecord looks like this:

public class ExtendedUserPartRecord : ContentPartRecord
{
	public virtual UserPartRecord UserPartRecord { get; set; } //Orchard.Users
        public virtual MyUserPartRecord RmsUserPartRecord { get; set; }  //My extended data
}

But I want something like this:

public class ExtendedUserPartRecord : ContentPartRecord
{
	public virtual string UserName { get; set; } //Comes from Orchard.Users
	public virtual string Email { get; set; } //Comes from Orchard.Users
        public virtual string PhoneNumber { get; set; }    //From my database table
        public virtual int Salary{ get; set; }     //From my database table
}
Coordinator
Sep 29, 2011 at 7:13 AM

The record must be a record (a database record). That's its only responsibility. It shouldn't proxy for something else. That is what the part should be doing.

Developer
Sep 29, 2011 at 8:01 AM

And you really shouldn't duplicate UserPart properties, but if you really want to access them more or less directly, then proxy to them from your part (and store a UserPart in your part). But I think the better way is to use As() as I mentioned.

Sep 29, 2011 at 9:46 AM
Edited Sep 29, 2011 at 9:48 AM
bertrandleroy wrote:

The record must be a record (a database record). That's its only responsibility. It shouldn't proxy for something else. That is what the part should be doing.

Thanks, I will try to use records only in right places

Sep 29, 2011 at 9:48 AM
Edited Sep 29, 2011 at 9:48 AM
Piedone wrote:

And you really shouldn't duplicate UserPart properties, but if you really want to access them more or less directly, then proxy to them from your part (and store a UserPart in your part). But I think the better way is to use As() as I mentioned.

I try to use filters, and it 'cast' successfully but all properties are equal NULL

Developer
Sep 29, 2011 at 10:17 AM

Hmm, this isn't good. Are your adding the filter to the constructor of the handler? I'm not sure if that means that the filter is not pickedup or something else is wrong.

Alternatively you can try to add an AlterTypeDefinition() to Migrations like the Orchard.Pages does (altering the User Type), but I think this is unnecessary and the filter should work.

Sep 29, 2011 at 12:13 PM

If this filter not added then As<>() returns NULL. With filter it returns needed object but with NULL properties.

Oct 6, 2011 at 12:25 PM

I think the best solution of my problem is this:

public class ExtendedUserPartRecord : ContentPartRecord
{
    public virtual UserPartRecord UserPartRecord { get; set; }

    // ...

    public virtual string PhoneNumber { get; set; }
    public virtual int Salary { get; set; }
}

With following part:

public class ExtendedPart : ContentPart<ExtendedUserPartRecord>
{
    public string UserName
    {
        get { return Record.UserPartRecord.UserName; }
        set { Record.UserPartRecord.UserName = value; }
    }

    // ...

    public string PhoneNumber
    {
        get { return Record.PhoneNumber; }
        set { Record.PhoneNumber = value; }
    }
}