How to add nest collection lists items?

Sep 17, 2012 at 5:24 AM
Edited Sep 17, 2012 at 5:25 AM

Hi,

I just wonder is there's ways to  to that. How?

 How to convert nest collection from domainmodel to datamodel?

Developer
Sep 17, 2012 at 6:21 PM

Hi,

I am not sure if I am understanding your scenario. It would be helpful if you could provide us with more detailed information about what your are you trying to achieve, so that we can help you further with this.

Regards,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Sep 18, 2012 at 2:34 AM

Hi DCherubini,

These are the errors messages

Cannot implicitly convert type 'Everest.DAL.Model.ContactAddress' to 'System.Collections.Generic.IEnumerable<Everest.BLL.Model.ContactAddress>'. An explicit conversion exists (are you missing a cast?)

Cannot implicitly convert type 'Everest.DAL.Model.ContactAddress' to
'System.Collections.Generic.IEnumerable<Everest.Domain.ContactAddress>

How to convert Type to Type from different layer to other layer?

I need the right pattern, don't get me wrong. This is DTO?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Everest.Domain

{

//Lives at Domain layer

public class ContactModel

{

public ContactModel()

{

}

public Guid ContactID { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public virtual ICollection<ContactAddress> ContactAddresses { get; set; }

}

//Lives at Domain layer

public class ContactAddressModel

{

public Guid AddressID { get; set; }

public string Address { get; set; }

public string City { get; set; }

public virtual Contact Contact { get; set; }

}

}

namespace Everest.Model

{

//Belong to .EDMX

public partial class Contact

{

public Contact()

{

}

public Guid ContactID { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public virtual ICollection<ContactAddress> ContactAddresses { get; set; }

}

//Belong to .EDMX

public partial class ContactAddress

{

public Guid AddressID { get; set; }

public string Address { get; set; }

public string City { get; set; }

public virtual Contact Contact { get; set; }

}

}

 

Developer
Sep 18, 2012 at 7:57 PM
Edited Sep 18, 2012 at 8:02 PM

Hi,

Based on my understanding of your scenario, in order to avoid this kind of exception you should have to add the necessary transformation logic to convert models in one layer to the specific implementation in the other layer, as in some cases this mapping may not be straightforward and could require some custom logic to achieve it.

As far as I know the MileageStats solution fulfills this conversions by using Static methods where this logic resides. Although, the custom implementation of this logic will depend on the requirements of your scenario and the data that will be exposed by your models, as an example of this approach, I believe you could check the following methods in the UserServices class in MileageStats.Domain project:

internal static Model.User ToDataModelUser(User userToConvert)

internal static User ToServiceUser(Model.User dataUser)

I hope you find this useful,

Agustin Adami
http://blogs.southworks.net/aadami

Sep 18, 2012 at 9:53 PM
Edited Sep 18, 2012 at 9:56 PM

Hi aadami,

Thanks, That's it. My $100 in Thai rate. This is really really great solution for me!!! 555

Sep 19, 2012 at 2:09 AM
Edited Sep 19, 2012 at 2:10 AM

Hi,

Again shall I mix DataModel plus DomainModel?

 

Best Regard,

WP

Developer
Sep 19, 2012 at 6:56 PM

Hi,

In my opinion, I would avoid mixing the different concerns of each layer. Ideally, the Data Access Layer should not contain any UI or application logic and should fully abstract the underlying storage implementation. This way, when you separate concerns that are specific to data access from those that are specific to the application's logic, the application remains robust and maintainable as you add features over time.

For guidance about whether or not to create a separate domain model. I believe you could check the "Composing Application Logic" section from the Silk's documentation.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Sep 20, 2012 at 7:40 AM

Hi Aadami,

Thanks again, these are really worth to read.

Best Regards,

WP

Sep 20, 2012 at 7:36 PM
Edited Sep 20, 2012 at 7:57 PM

Hi aadami,

Why do the team place Data model from Data Access layer at JScript>>Models folder to viewModel?

And seems like the team Mix DAL's model + Domain's model

At least there's 3 kind of models lives in diffrent layers.

1. Data Access layer.

2. Domain layer.

3. JScript Models folder.

Do you mean if we can use the whole Domain's model is best?

In one of my viewmodel I use model from DAL.

Best Regards,

WP

Developer
Sep 21, 2012 at 8:43 PM


Hi,

Based on my understanding, if you are referring to the JSonViewModels which are used to define the structure that will be returned as the result of the ajax calls. As far as I know, these models are created based on the Domain Models exposed by the Domain Layer (which will end up calling the models from the Data Access Layer). In other words I believe that, using this approach the different concerns can be separated, as the Domain models will be focused on handling the business logic, Data models handle data access logic and will be encapsulated by a service layer and ViewModels will be focused on presentation. As an example of this you could check the JsonDetails action defined in the VehicleController class.

Take into account that which approach you used will depend on your design decisions, as you would have to analyze if the benefit of having a separate domain model will result for your application.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Sep 22, 2012 at 7:38 AM
Edited Sep 22, 2012 at 11:18 PM

Hi aadami,

I am very very appreciate your help but my issues still persist there. This would be the last Q that I would like to ask you if you can.

Q: Shall we use a DomainModel for each View(UI or per a Process)?

I cannot convert one to many when I return collections items(as you can see from above)

I return collection of the Contact entity

E.G

1. Collection of Contact enity then convert to ContactModel

ID             Name          Telephone

100          Apple           012-321-4563

101          Ham             456-879-6325

102          Donus          859-456-9876

There's no problem with convert Contact to ContactModel, but each Contact item has Relationship to

public virtual ICollection<ContactAddress> ContactAddresses { get; set; }

I don't know how to convert the ContactAddresses to ContactAddressesModel.

E.G

IEnumerable<ContactModel> items = this.entityRepository.GetContactByObj(factor).Select(o => new ContactModel
                {
                    ContactID = o.ContactID,
                    Address = o.ContactAddresses.Select(x => new ContactAddressModel
                    {
                        Filed1 = x.Address1,
                        Field2 = x.Address2
                    })
                });

As you know each Contact item has multiple values of ContactAddresses

E.G

100 Apple 012-321-4563 ->> {1. 54/9 Australia, 2.USA, 3. Monglolia}.

101 Ham 456-879-6325 ->> {1. 14/9 Swizerland, 2.vienam}.

102 Donus 859-456-9876 ->  {1. 74/9 Erac, 2.Thai, 3. Lao}.

I have no problem when return an item of Contact. I can convert it.

Best Regards,

Weera

Developer
Oct 1, 2012 at 8:48 PM
Edited Oct 2, 2012 at 7:51 PM

Hi everybody,

In my opinion, how to resolve the scenario that Weera is mentioning will depend mostly of how and what you need to pass between the Domain and Data layers.

For example, if your ContactModel has a collection of ContactAdressModels, a simple approach could be to convert each element one by one manually by doing something like this:

/* WARNING - The following is psedo-code. May need to be changed in order to work */

// Supposing GetContactsByObj returns a list of Contacts
IEnumerable<Contact> rawItems = this.entityRepository.GetContactsByObj(factor);
List<ContactModels> items = new List<string>();

foreach(var rawItem in rawItems)
{
	var item = new ContactModel()
	{
		ContactID = rawItem.ContactID,
		FirstName = rawItem.FirstName,
		LastName = rawItem.LastName
	};

	foreach(var rawAddress in rawItem.ContactAddresses)
	{
		var address = new ContactAddressModel()
		{
			AddressID = rawAddress.AddressID,
			Address = rawAddress.Address,
			City = rawAddress.City,
			ContactModel = item
		}
		
		item.ContactAddressModels.Add(address);
	}

	items.Add(item);
}

 

However, this is only one approach and might not be suitable for all scenarios (for example, it might cause problems when having a many-to-many relationship between models.)

On the other hand, it's not required for the data model and the domain model to have exactly the same properties. In the case of MileageStats, there are domain models that contain only the information of the data model that is required. An example of this are the Vehicle (data) and VehicleModel (domain) classes. The Vehicle data model contains two collections, one of FillupEntries and other of Reminders. However, these collections don't exist in the VehicleModel.

Instead of transforming the Reminders collection to a collection of ReminderSummaryModels and storing it in the VehicleModel, MileageStats simply ignores it; and when those are required, MileageStats obtains the corresponding Reminders for that Vehicle directly from the repository. This can be seen, for example, in the GetVehicleListForUser and the GetOverdueRemindersForVehicle handlers. By doing something like this, it is possible to have simple domain models without needed to worry about converting its internal collections, as the items of those collections are later accessed separately by other means.

Again, which approach you should follow will depends of the requirements of each scenario and your personal preferences.

I hope this helps,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Oct 4, 2012 at 3:10 AM
Edited Oct 4, 2012 at 3:11 AM

Hi DCherubini,

Thanks for sharing your code. I like this domain concept. I love your code.