Im using automapper to object conversion where source is table class and destination is property class.
I'm using .dml to connect database.
App type - Window
Using platform - VS-12 framework 4.5 , automapper version 4.2.1
Issues :- when convert single class object automapper successfully converted but when im using list then it return zero.
In Config class-
public static Initialize();
Mapper.CreateMap<Source, destination>().ReverseMap();
Mapper.CreateMap<List<Source>, List<destination>>().ReverseMap();
In code-
//It run successfully
Mapper.map(result, objdestination);
//It not run work and anot giving any exception
Mapper.map(listresult, listdestination);
Thanks in advance.
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap< Source, destination>().ReverseMap();
});
config.AssertConfigurationIsValid(); // check if configuration valid.
IMapper mapper = config.CreateMapper();
var appProduct = mapper.Map<List<destination>>(sourceObj);
Related
I have a TypeConverter in which I'm using context.Mapper.Map() to map two subproperties.
The properties are the same Type and use the same (another) TypeConverter. However in one the properties I need to pass some IMappingOperationsOptions.
It looks like this (simplified):
public class MyTypeConverter : ITypeConverter<A, B>
{
public B Convert(A, B, ResolutionContext context)
{
var subProp1 = context.Mapper.Map<C>(B.SomeProp);
var subProp2 = context.Mapper.Map<C>(B.SomeOtherProp, ops => ops.Items["someOption"] = "someValue");
return new B
{
SubProp1 = subProp1,
SubProp2 = subProp2
};
}
}
This was working fine in AutoMapper 8.0.0 but I'm upgrading to AutoMapper 10.1.1 (last version with .NET framework support).
In this newer version of AutoMapper the overload method to pass IMappingOperationsOptions does not exist anymore.
I could (theoretically) solve this by injecting IMapper in the constructor of the TypeResolver and use that instead of the ResolutionContext's Mapper but that doesn't feel right.
At the moment I solved the issue by temporarily updating the ResolutionContext options, but that also doesn't really feel right.
var subProp1 = context.Mapper.Map<C>(B.SomeProp);
context.Options.Items["someOption"] = "someValue";
var subProp2 = context.Mapper.Map<C>(B.SomeOtherProp);
context.Options.Remove("someOption");
Casting ((IMapper)context.Mapper).Map() crashes so that's not an option either. Is there a more elegant way to achieve this?
I am using MiniProfiler in my project. To get an instance of the MiniProfiler, i have to use the following:
var profiler = MiniProfiler.Current;
This profiler object is what I want AutoFac to pass to every MiniProfiler Type when I create a class. Example I did the following:
var profiler = MiniProfiler.Current;
builder.RegisterInstance(profiler);
and in my controller I use the following way:
public ListingsController(IDataFetcher DataFetcher, ILog log, MiniProfiler profiler)
{
_DataFetcher = DataFetcher;
_log = log;
_profiler = profiler;
}
The thing is the profiler instance can be null and I get the following server error when i run the code.
Value cannot be null.
See image:
What needs to be done so that I can use Autofac with Miniprofiler? Or am I registering the object to the concreteType correctly?
Try registering a lambda so it's always the current instance instead of one specific instance.
builder.Register(
c => MiniProfiler.Current)
.As<MiniProfiler>();
My PLUGIN is firing on Entity A and in my code I am invoking a web service that returns an XML file with some attributes (attr1,attr2,attr3 etc ...) for Entity B including GUID.
I need to update Entity B using the attributes I received from the web service.
Can I use Service Context Class (SaveChanges) or what is the best way to accomplish my task please?
I would appreciate it if you provide an example.
There is no reason you need to use a service context in this instance. Here is basic example of how I would solve this requirement. You'll obviously need to update this code to use the appropriate entities, implement your external web service call, and handle the field updates. In addition, this does not have any error checking or handling as should be included for production code.
I made an assumption you were using the early-bound entity classes, if not you'll need to update the code to use the generic Entity().
class UpdateAnotherEntity : IPlugin
{
private const string TARGET = "Target";
public void Execute(IServiceProvider serviceProvider)
{
//PluginSetup is an abstraction from: http://nicknow.net/dynamics-crm-2011-abstracting-plugin-setup/
var p = new PluginSetup(serviceProvider);
var target = ((Entity) p.Context.InputParameters[TARGET]).ToEntity<Account>();
var updateEntityAndXml = GetRelatedRecordAndXml(target);
var relatedContactEntity =
p.Service.Retrieve(Contact.EntityLogicalName, updateEntityAndXml.Item1, new ColumnSet(true)).ToEntity<Contact>();
UpdateContactEntityWithXml(relatedContactEntity, updateEntityAndXml.Item2);
p.Service.Update(relatedContactEntity);
}
private static void UpdateContactEntityWithXml(Contact relatedEntity, XmlDocument xmlDocument)
{
throw new NotImplementedException("UpdateContactEntityWithXml");
}
private static Tuple<Guid, XmlDocument> GetRelatedRecordAndXml(Account target)
{
throw new NotImplementedException("GetRelatedRecordAndXml");
}
}
I need to trace any complex (i.e. non-default) mappings in our project.
To achieve this, I'm using a custom value resolver, and publishing out a log event during resolution. As part of this message I'd like to know the destination member being mapped, which I was hoping to find in source.Context.MemberName - but this is always null.
ValueResolver:
public class Resolver : IValueResolver
{
public event MappingEventHandler MappingEvent;
public delegate void MappingEventHandler(MappingMessage m);
public ResolutionResult Resolve(ResolutionResult source)
{
var src = (SourceDTO)source.Context.SourceValue;
if (!String.IsNullOrWhiteSpace(src.Status) && src.Status == "Alert")
{
var newValue = source.Value + " - Fail";
var fieldName = source.Context.MemberName; //Always null
MappingEvent(new MappingMessage(fieldName , newValue));
return source.New(value, typeof(String));
}
return source;
}
}
... and its usage:
Resolver resolver = new Resolver();
//... subscribe to resolver events etc.
Mapper.CreateMap<SourceDTO, Common>()
.ForMember(dest => dest.ReferenceIdentifier
, opt => opt.ResolveUsing<Resolver>()
.FromMember(src => src.Reference)
.ConstructedBy(() => resolver)
I can see in the Automapper code that MemberName only returns if the PropertyMap is non-null, and since PropertyMap is null in this case, I'm not getting my MemberName back.
Is there a reason the PropertyMap isn't being defined in this here? There's a relevant candidate via source.Context.TypeMap.GetPropertyMaps(), but it's not being pushed into this context.
Any ideas? Perhaps there's a means of pulling the right PropertyMap out of the Context.TypeMap set?
Tried with the more recent Automapper build - looks like the problem has been resolved.
Version with issue: 2.1.266
Working version: 2.2.1
Also found it's a lot easier to use the following syntax to resolve from an existing instance:
Resolver resolver = new Resolver();
//... subscribe to resolver events etc.
Mapper.CreateMap<SourceDTO, Common>()
.ForMember(dest => dest.ReferenceIdentifier
, opt => opt.ResolveUsing(resolver)
.FromMember(src => src.Reference) )
I'm trying to re-use some of the model configurations on several entities that implements a interface.
Check this code:
public static void ConfigureAsAuditable<T>(this EntityTypeConfiguration<T> thisRef)
where T : class, IAuditable
{
thisRef.Property(x => x.CreatedOn)
.HasColumnName("utctimestamp")
.IsRequired();
thisRef.Property(x => x.LastUpdate)
.HasColumnName("utclastchanged")
.IsRequired();
} // ConfigureAsAuditable
as you can see I'm trying to call the extension method "ConfigureAsAuditable" on my onmodelcreating method like this:
EntityTypeConfiguration<Account> conf = null;
conf = modelBuilder.Entity<Account>();
conf.ToTable("dbo.taccount");
conf.ConfigureAsAuditable();
When debugging i get this exception:
The property 'CreatedOn' is not a declared property on type
'Account'. Verify that the property has not been explicitly excluded
from the model by using the Ignore method or NotMappedAttribute data
annotation. Make sure that it is a valid primitive property.
Thanks in advance :)
PD:
I'm using EF 5-rc, VS 2011 and .NET Framework 4.5
I think a better approach would be to implement your own derived version of EntityTypeConfiguration. For example:
public class MyAuditableConfigurationEntityType<T> : EntityTypeConfiguration<T>
where T : class, IAuditable{
public bool IsAuditable{get;set;}
}
Then, when building your model, use that new type:
var accountConfiguration = new MyAuditableConfigurationEntityType<Account>();
accountConfiguration.IsAuditable = true; // or whatever you need to set
accountConfiguration.(HasKey/Ignore/ToTable/Whatever)
modelBuilder.Configurations.Add(accountConfiguration);