0

I was wondering if someone could help me understand RavenDB transformations as I cant seem to get them working correctly. I tried following Ayende's post but I am not able to apply it to my situation. I have two models, a UserModel and an UserAddressModel. The code is as follows

public class UserModel
    {
        #region Properties

        public string Id { get; set; }

        public string AccountId { get; set; }

        public string UserName { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string Email { get; set; }

        public DateTime InsertDate { get; set; }

        #endregion 
    }

and

public class UserAddressModel
    {

        public string Id { get; set; }

        public string AccountId { get; set; }

        public string Address1 { get; set; }

        public string Address2 { get; set; }

        public string City { get; set; }

        public string State { get; set; }

        public string Zipcode { get; set; }

        public float Latitude { get; set; }

        public float Longitude { get; set; }

        public DateTime InsertDate { get; set; }

    }

I have my RavenDB Index set up like such.

public class UserDashboard_ByName : AbstractIndexCreationTask<UserModel>
    {
        public UserDashboard_ByName()
        {
            Map = users => from user in users
                                   select new { user.UserName, user.AccountId };

            TransformResults =
                (database, users) => from user in users
                                             let useraddress = database.Load<UserAddressModel>(user.AccountId)
                                             select new
                                                        { FirstName = user.FirstName,
                                                          LastName = user.LastName,
                                                          Address1 = useraddress.Address1,
                                                          Address2 = useraddress.Address2

                                                        };
        }
    }

and I am calling it with the following code

using (var session = DataDocumentStore.Instance.OpenSession())
            {

                //Get the AccountId
                var userDashboard =
                (from user in session.Query<UserModel, UserDashboard_ByName>()
                 where user.UserName == userName
                 select user).SingleOrDefault();


            }

When I call the index, it returns a UserModel type, not the anonymous type that I am expecting. Also, I do not understand how I can call

let useraddress = database.Load<UserAddressModel>(user.AccountId)

when there is no specific relationship that has been specified in code or anywhere else.

Maybe someone can explain to me how I should be joining data in RavenDB? Some expanded documentation or a nudge in the right direction to understanding this better would be greatly appreciated. Thanks in advance.

4

2 回答 2

1

You need to create another model (a view model basically), such as UserWithAddressModel that includes the 4 properties you wish to return:

public class UserWithAddressModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }    
        public string Address1 { get; set; }
        public string Address2 { get; set; }
    }

Then do your query like this:

var userDashboard =
                (from user in session.Query<UserModel, UserDashboard_ByName>()
                 where user.UserName == userName
                 select user).As<UserWithAddressModel>().SingleOrDefault();

I think this is what you are looking for.

UPDATE:

Try like this:

var userDashboard = session.Query<UserModel, UserDashboard_ByName>()
    .Where(x => x.UserName == userName)
    .As<UserWithAddressModel>()
    .SingleOrDefault();

UPDATE2:

Sorry, just looked again at what you are trying to do, it won't work like that. I thought you had a reference to your UserAddressModel in your UserModel (such as UserAddressId).

Why are you splitting the 2 models up in the first place if they are a 1:1 relation?

于 2012-05-02T20:52:11.150 回答
1

The problem is inside your TransformResult function where you call database.Load<UserAddressModel>(user.AccountId). You can only load the UserAddressModel with its id, not by a property like AccountId.

You have to store the id of the UserAddressModel inside your UserModel if you want to do it that way. However, I wouldn't model it in that way. UserAddressModel doesn't have any meaning on itself, so it should probably be part of UserModel. As a rule of thumb, you generally want to have your aggregrate roots as documents and everything else inside them.

于 2012-05-02T22:21:05.330 回答