Automapper - How to reuse objects instead of creating new ones (this objects are in a list) - automapper

I got the following problem:
I got a Entity (from EF Code First) that looks like this.
public class Movie {
public ICollection<AudioQuality> AudioQualities {get;set;}
}
public class AudioQuality {
public Guid Id{get;set;}
public int Channels{get;set;}
}
//Automapper Init:
Mapper.CreateMap<Movie, MovieDto>();
Mapper.CreateMap<MovieDto, Movie>().ForMember(dest => dest.AudioQualities,opt => opt.UseDestinationValue());
Mapper.CreateMap<VideoQuality, VideoQualityDto>();
Mapper.CreateMap<AudioQuality, AudioQaulityDto>();
Mapper.CreateMap<VideoQualityDto, VideoQuality>();
Mapper.CreateMap<AudioQaulityDto, AudioQuality>()
.ForMember(dest => dest.Movies, opt => opt.Ignore());
And I also got a DTO that looks similar!
I map from the DTO to the Entity like so:
//Get Movie from DB and than update it with the dto values
Movie movieFromDb = GetMoviesWithAllChilds().Single(mov => mov.Id == movieDto.Id);
//use update the entity from db with dto
Mapper.Map(movieDto, movieFromDb);
Now the problem is, that Automapper creates a new AudioQuality-Object for each item in AudioQualities.
But I want that he just copies the values from the AudioQuality-Objects from the DTO to the Entities instead of creating new Objects with the values from the DTO.
Is there a way to do that??
FYI: UseDestinationValue works on the collection (so the collection is not copied).
br rene_r

Get your entity from the context and pass it in to the Mapper function as the second parameter. The updates will eb applied from the source to the destination.
mapper.Map<SourceType, DestType>(source, dest);

Related

Need to verify Autommaper implemented correctly in Asp.Net MVC

I have implemented Automapper in my MVC project but not sure if it is been done correctly. I am currently using Entity Framework Database First Approach and retrieving data using stored procedures. As you would be aware Entity Framework creates complex type object which is a wrapper around Stored Procedures.So I have created two classes for mapping purpose. One is used in the repository class to map the complex type to Entity class and second is the viewmodel that is used to map the entity class to view model in the controller. I havent explicitly mapped my entity class to viewmodel in the controller. So I am wondering how is the data bound to the grid as the grid is expecting viewmodel. I am looking forward for suggestions in terms of the approach that I have taken.
spGetUserProfileByUserProfileID_Result - Complex type object
UserProfile - Entity class.
UserProfileViewModel - ViewModel
AutoMapperConfiguration Class
public static void Configure()
{
Assembly[] assemblies = BuildManager.GetReferencedAssemblies().OfType<Assembly>().ToArray();
Mapper.Initialize(cfg =>
cfg.AddProfiles(AllClasses.FromAssemblies(assemblies)
.Where(
a =>
a.FullName.EndsWith("Mapping"))));
}
Mapping class
public class DomainToModelMapping : Profile
{
public DomainToModelMapping()
{
CreateMap<spGetUserProfileByUserProfileID_Result, UserProfile>().ReverseMap();
CreateMap<UserProfileViewModel, UserProfile>().ReverseMap();
}
}
Repository
public List<UserProfile> GetUserProfileById(int id)
{
if (MCRHelper.UserValidate() == 1)
{
var userProfiles = db.spGetUserProfileByUserProfileID(id);
return Mapper.Map<List<UserProfile>>(userProfiles);
}
else
{
return null;
}
}
Controller
public ActionResult UserProfile_Read([DataSourceRequest]DataSourceRequest request)
{
var response = mcrRepository.GetUserProfileById(0).ToDataSourceResult(request);
return Json(response, JsonRequestBehavior.AllowGet);
}
If I add the following , to my controller to map to viewmodel, I get an error Missing type map configuration or unsupported mapping.
Mapping types:
DataSourceResult -> UserProfile
Kendo.Mvc.UI.DataSourceResult -> CC.GRP.MCRequest.Models.UserProfile
var userProfile = mcrRepository.GetUserProfileById(0).ToDataSourceResult(request);
return Json(Mapper.Map<UserProfile>(userProfile), JsonRequestBehavior.AllowGet);
If your question is how to return the viewmodel instead of the entity model from your controller using Automapper, then use Automapper Queryable Extensions:
using Automapper.QueryableExtensions;
...
public JsonResult UserProfile_Read([DataSourceRequest]DataSourceRequest request)
{
var users = mcrRepository.GetUserProfileById(0).Project().To<UserProfileViewModel>();
var response = users.ToDataSourceResult(request);
return Json(response, JsonRequestBehavior.AllowGet);
}

Servicestack - Ormlite - high volume data loading

I am getting some issues with Servicestack and OrmLite in high data loading scenarios.
Specifically,
1. I have a list of 1000 000 + entities
2. I would like to insert them into Db (using Sql Server) if record does not exist yet
Thus,
public class Entity
{
[Autoincrement]
public int Id {get;set;}
public string Name {get;set;}
public string Address {get;set;}
}
Now for the import logic,
List<Entity> entities = oneMillionEntities.ToList();
foreach (var entity in entities)
{
if (!db.Exists<Entity>(ar => ar.Address == entity.Address))
{
db.Save(entity);
}
}
Issue is that quite often db is still busy with save action thus db.Exists does not always produce correct result. What is the best way of handling these scenarios?
Try
// Prepare SqlExpression
var ev = Db.From<Entity>().Select(p => p.Address).GroupBy(p => p.Address);
// Execute SqlExpression and transform result to HashSet
var dbAddresses = Db.SqlList(ev).ToHashSet();
// Filter local entities and get only local entities with different addresses
var filteredEntities = oneMillionEntities.Where(p =>
!dbAddresses.Contains(p.Address));
// Bulk insert
db.InsertAll(filteredEntities.ToList());

Passing Interfaces into Dictionary key's

I have been following following coreclr for a little while and I am new to programming. My question is why do they pass interfaces into Dictionary's especially the key value?
//
// Allocate a new Dictionary containing a copy of the old values, plus the new value. We have to do this manually to
// minimize allocations of IEnumerators, etc.
//
Dictionary newValues = new Dictionary(current.m_localValues.Count + (hadPreviousValue ? 0 : 1));
My understanding is that interface is to implemented by a class. Once implemented it can call/use functions or store data in the classes properties/ variables. I am missing some understanding of interfaces and their use cases but I do not know what that it.
Why do you instantiate a variable to an interface or pass an interface into a parameter? My understanding is you will then have an instance of that variable which still can't hold values nor change state through methods.
Let me explain.
Interface is contract. It just contains method without implementation. Now it may possible that that interface is being implemented by any number of class.
public interface IEntity { int Id {get;set;} }
public class Student : IEntity { public int Id {get;set;} // Interface Property }
public class Teacher : IEntity { public int Id {get;set;} // Interface Property }
Dictionary<IEntity,object> obj = new Dictionary<IEntity,object>(); Student s = new Student(); Teacher t = new Teacher(); obj.Add(s,any object); obj.Add(t,any object);
This is because of interface that your dictionary can hold reference of both type ( Student and Teacher).
In .NET when any object is created it is uniquely identify by GetHashCode() method. // You can find more detail on this on MSDN.
Also Dictionary not means that keys must be only primitive type. This is the reason it is good if you have more than one key ( Like composite key in Database) so it allow you to identify uniquely based on your custom implementation.
Now second Generic.
public class PersonInfo<T> where T : IEntity
{
public string Name {get;set;}
public T Entity {get;set;}
}
PersonInfo<Student> student = new PersonInfo<Student>();
student.T = new Student();
student.Name = "";
PersonInfo<Teacher> Teacher = new PersonInfo<Teacher>();
teacher.T= new Teacher();
teacher.Name = "";
When you have interface. It not actually interface. You always have a reference to object with that interface. And that object is the one responsible for comparison in dictionary
The benefit is not difference from using class as a key. Dictionary can be used as list to iterate KeyValuePair to take key to do some operation. But using interface means you can store various type of class with same interface instead of just one type. Which is decoupled and more flexible

Get media picker field content of a custom part in Orchard

I created a custom part using the content picker field.
public int UpdateFrom1()
{
ContentDefinitionManager.AlterPartDefinition("BackgroundPart",
builder => builder.WithField("BackgroundImage",
fieldBuilder => fieldBuilder
.OfType("MediaPickerField")
.WithDisplayName("Background Image")));
return 2;
}
public int UpdateFrom2()
{
ContentDefinitionManager.AlterTypeDefinition("Background", cfg => cfg
.WithPart("BackgroundPart")
.Creatable()
.Indexed());
return 3;
}
The service code for getting the data:
public class BackgroundService : IBackgroundService
{
private readonly IRepository<BackgroundPartRecord> _repository;
public BackgroundService(
IRepository<BackgroundPartRecord> repository,
ISignals signals)
{
_repository = repository;
}
public IEnumerable<BackgroundPartRecord> Get()
{
return _repository.Table;
}
}
This works (i can pick content when I create an new item of this type).
Now I want to get a list of all items of my type. I created a service for that and I get a list of my created items. But the items in the list don't have the media picker field. How do I get this content? I want to use this in OnResultExecuting method in a FilterProvider class in my module.
That can't work because you're using the repository API. Repository is a low-level API that is used internally, but should rarely, if ever be used by modules. One of the reasons is that it won't get content items, just part records.
Instead, you need to use one of the querying APIs from ContentManager. That will give you real content items that you can do As on, that will give you access to the content item's fields (those are stored on the Infoset, which is on the content item record), etc.
This or one of the overloads and extension methods should do the trick:
_contentManager.Query<BackgroundPart>()

Automapper and access to member variables

I have an mvc controller which has a helper class injected into it. I would like to convert from a viewmodel to a dto using automapper. most of the properties are simple mappings but one involves calling the helper class with a parameter from the viewmodel. Ideally I would want to do something like this:
Mapper.CreateMap<TheViewModel, TheDto>()
.ForMember(dest => dest.Url, o => o.MapFrom(src => _urlHelper.GenerateUrlFromUsername(src.Username)));
...but I cannot because I cannot access a non-static field.
What is the best approach?
EDIT:
OK, so I have a custom resolver but how do I hook this in to my IoC container?
public class CustomResolver : ValueResolver<TheViewModel, string>
{
private readonly IUrlHelper _urlHelper;
public CustomResolver(IUrlHelper urlHelper)
{
_urlHelper = urlHelper;
}
protected override string ResolveCore(TheViewModel source)
{
return _urlHelper.GenerateUrlFromUsername(source.Username);
}
}
Use a custom resolver in this case:
http://automapper.codeplex.com/wikipage?title=Custom%20Value%20Resolvers
Custom resolvers can be instantiated from a container, so you can get whatever instance fields of services you need.

Resources