Ich habe den folgenden Satz von Klassen (nur in einer Richtung, von Data*
bis Api*
) zuzuordnen:Prevent AutoMapper Zeichenfolge als Sammlung in LINQ ProjectTo zu behandeln
// Top level
public class DataEntity
{
public NestedDataEntity Nested { get; set; }
// ... other primitive/complex properties
}
public class ApiEntity
{
public NestedApiEntity Nested { get; set; }
// ... other primitive/complex properties
}
// Nested level
public class NestedDataEntity
{
public string Items { get; set; }
}
public class NestedApiEntity
{
public IEnumerable<ApiSubItem> Items { get; set; }
}
public class ApiSubItem
{
// there are properties here. Not needed for the sake of example
}
Mapping innerhalb eines Profile
wie in konfiguriert ist, das folgende Stück Code:
// mapping profile
public class MyCustomProfile : Profile
{
public MyCustomProfile()
{
CreateMap<DataEntity, ApiEntity>();
CreateMap<NestedDataEntity, NestedApiEntity>();
CreateMap<string, IEnumerable<ApiSubItem>>()
.ConvertUsing<TextToSubItemsConverter>();
}
}
// type converter definition
public class TextToSubItemsConverter :
ITypeConverter<string, IEnumerable<ApiSubItem>>
{
public IEnumerable<ApiSubItem> Convert(
string dataItems, IEnumerable<ApiSubItem> apiItems, ResolutionContext context)
{
// actually, deserialize & return an ApiSubItem[]
// here just return some fixed array
return new ApiSubItem[]
{
new ApiSubItem(),
new ApiSubItem(),
new ApiSubItem(),
};
}
}
// Main
public class Program
{
public static void Main(string[] args)
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile<MyCustomProfile>();
});
Mapper.AssertConfigurationIsValid();
DataEntity dataEntity = new DataEntity()
{
Nested = new NestedDataEntity()
{
Items = "Ignored text",
},
};
// This maps ok, no issues
ApiEntity apiEntity = Mapper.Map<DataEntity, ApiEntity>(dataEntity);
IQueryable<DataEntity> dataEntities = new[] { dataEntity }.AsQueryable();
// This exposes the System.Char to ApiSubItem issue
ApiEntity apiEntityProjected = dataEntities.ProjectTo<ApiEntity>().First();
}
}
Mapping Konfiguration geht Erstvalidierung beim Start, aber dann, wenn eine tatsächliche Mapping erforderlich ist ich Ausnahme:
System.InvalidOperationException: Fehlende Zuordnung von System.Char zu my.whatever.namespace.ApiSubItem. Erstellen Sie mit Mapper.CreateMap.
Wenn ich zwischen string
und IEnumerable<ApiSubItem>
, Erstvalidierung beschwert sich über den gleichen Kontext vollständig die Konfiguration auslassen:
Kontext: Mapping von Typ System.Char my.whatever.namespace.ApiSubItem
Wenn es hinzugefügt wird, scheint es, dass es nicht von AutoMapper aufgenommen wird.
Die Zuordnung erfolgt in einem statischen Kontext durch einen ProjectTo<ApiEntity>()
-Aufruf über die LINQ-Abfrage über DbSet<DataEntity>
. Ich habe überprüft, dass der Konverter keine Abhängigkeit erfordert, nur für den Fall.
AutoMapper ist 5.0.2 und wird in einer MVC API-Webanwendung unter ASP.Net Core 1 RTM ausgeführt.
Ich habe ähnliche Fragen hier auf SO überprüft, aber ohne Glück. Weiß jemand, wie man diese Art von Szenario funktioniert? Ich denke, ich bin nicht der erste, der versucht, (Auto) von einer string
zu einer Sammlung zu mappen. TA
EDIT hinzugefügt beide versagen und nicht versiegende Fall zu Beispiel
EDIT 2 Nach weiteren suchen, schlug irgendwo jemand das Feld zu ignorieren und führen Mapping in AfterMap()
. Mit diesem Profil wird keine Ausnahme ausgelöst, aber resultierende Items
Feld ist null:
CreateMap<DataEntity, ApiEntity>();
CreateMap<NestedDataEntity, NestedApiEntity>()
.ForMember(api => api.Items, options => options.Ignore())
.AfterMap((data, api) =>
{
api.Items = Mapper.Map<IEnumerable<ApiSubItem>>(data.Items);
});
CreateMap<string, IEnumerable<ApiSubItem>>()
.ConvertUsing<TextToSubItemsConverter>();
EDIT 3 umformuliert Frage Titel, um es präziser für die Projektion
Sie können die Zeichenfolge nicht der Sammlung zuordnen. In diesem Fall müssen Sie die Datei items.propertyname packen, deren Rückgabetyp Zeichenfolge ist. weil automapper arbeiten eins zu eins Zuordnung –
können Sie eine [SSCCE] (http://sscce.org/) –
@PankajGupta können Sie mir bitte noch einmal sagen, ich kann es nicht bekommen. – superjos