My problem could be schematized like this :
I have a domain class represented like this
public class DomainClass {
public DateTime Begin {get; set;}
public DateTime End {get; set;}
public int Type {get;set}
}
And I have two distincts tables in database that matches different type :
public class TypeClassOne {
public DateTime Begin {get; set;}
public DateTime End {get; set;}
}
and
public class TypeClassTwo {
public DateTime Begin {get; set;}
public DateTime End {get; set;}
}
How can I configure AutoMapper to have a mapping like this
var config = new MapperConfiguration(c =>
{
c.CreateMap<DomainClass, TypeClassOne>()
.??? <= I would like OnlyIf(source => source.Type == 1)
}
I've tried ForMember, but it doesn't works at class level...
Anyone tried to do this ?
Related
Is it possible to convert an IDictionary into a class?
My IDictionary looks like this
{{DapperRow,
Date = '9/25/2014 12:00:00 AM',
UserId = '123456',
User = 'Timothy'
}}
my class
public class MyClass
{
public DateTime Date {get; set;}
public string User {get; set;}
public int UserId {get; set;}
public virtual someModel {get; set;}
}
To convert the dictionary you provided to the class you provided, you can just add a constructor to the model class to read the dictionary values.
public class MyClass
{
public DateTime Date { get; set; }
public string User { get; set; }
public int UserId { get; set; }
public MyClass(IDictionary<string, object> data)
{
Date = DateTime.Parse(data["Date"].ToString());
User = data["User"].ToString();
UserId = int.Parse(data["UserId"].ToString());
}
}
But Panagiotis is right, in this situation you should be taking advantage of dapper to automagically map data to your models for you. Their readme is incredibly helpful if you need to figure out how it works or how to do complex mappings.
I have following lagacy code. There is a seperation between Pesistence Model and the (anemic) Domain Model. What is the benefit of this seperation and the implicit conversion ? Do you see any drawbacks ?
I know that with implicit conversion following is possible:
SplitAmountEF saEF = dbContext.SplitAmount.Find(id);
SplitAmount sa = saEF; //implicit conversion.
They can be used interchangeable.
If the domain model is almost the same like persistence model, wouldnt it be better to use only the persistence model (without using Domain Model at all)?
Example:
//Domain Model
public class Booking
{
public Guid ID {get; set;}
....
}
public class SplitAmount
{
public Guid ID {get; set;}
public Decimal Amount {get; set;}
...
public Guid IDBooking {get; set;}
}
//Persistence Model
public class BookingEF
{
public Guid ID {get; set;}
...
}
public class SplitAmountEF
{
public Guid ID {get; set;}
public Decimal Amount {get; set;}
...
public virtual BookingEF Parent {get; set;}
//implicit converstion from SplitAmountEF to SplitAmount
public static implicit SplitAmount(SplitAmountEF saEF)
{
return new SplitAmount()
{
ID = saEF.ID,
Amount = saEF.Amount,
...
IDBooking = saEF.Parent.ID,
}
}
//implicit converstion from SplitAmount to SplitAmountEF
public static implicit SplitAmountEF(SplitAmount sa)
{
return new SplitAmountEF()
{
ID = sa.ID,
Amount = sa.Amount,
...
}
}
}
I am wondering if it is possible to make one table related to many.
This is what I got now (working one-to-zero-or-one relation between Report and ReportHeader):
public class Report
{
public int Id {get; set;}
public ReportHeader ReportHeader {get; set;}
[ForeignKey("ReportHeader")]
public int ReportHeaderId {get; set;}
}
public class ReportHeader
{
[Key, ForeignKey("Report")]
public int Id {get; set;}
public Report Report {get; set;}
}
At this point I want to add table named Style to Report BUT also to table ReportHeader. Thus, the relations would look like this:
Report
|--ReportHeader
| |-- Style
|
|-- Style
After that the classes should look like:
public class Report
{
public int Id {get; set;}
public ReportHeader ReportHeader {get; set;}
public Style Style {get; set;}
[ForeignKey("ReportHeader")]
public int ReportHeaderId {get; set;}
[ForeignKey("Style")]
public int StyleId {get; set;}
}
public class ReportHeader
{
[Key, ForeignKey("Report")]
public int Id {get; set;}
[ForeignKey("Style")]
public int StyleId {get; set;}
public Report Report {get; set;}
public Style Style {get; set;}
}
This is so much fun... until it comes to think about the Style class. At this point I have no idea how to design it. Is that even possible to make that class be in two relations with different tables?
public class Style
{
// ???
//[Key, ForeignKey("Report"), ForeignKey("ReportHeader")]
public int Id {get; set;}
public ReportHeader ReportHeader {get; set;}
public Report Report {get; set;}
}
At this case you should to mask your desired relation: one-to-one as many-to-one:
public BaseClass
{
//indeed, collection always will have zero or one items
public virtual ICollection<Style> styles {get; set;}
[NotMapped]
public Style style {
get { return styles.FirstOrDefault(); }
set { styles.Add(value); };
}
}
public class Report : BaseClass
{
//other stuff...
}
public class ReportHeader : BaseClass
{
//other stuff...
}
public class Style
{
public int Id {get; set;}
public virtual Report report {get; set;}
[Index(IsUnique = true)]//to ensure that relation is exactly one-to-one
public int? reportId {get; set;}
public virtual ReportHeader reportHeader {get; set;}
[Index(IsUnique = true)]//to ensure that relation is exactly one-to-one
public int? reportHeaderId {get; set;}
}
I have the following models (and corresponding DTOs):
public class Link
{
public int Id {get; set;}
public int FirstLinkId {get; set;}
public int SecondLinkId {get; set;}
public virtual Link FirstLink {get; set;}
public virtual Link SecondLInk {get; set;}
}
public class OtherObject
{
public int Id {get; set;}
public int LinkId {get; set;}
public string Name {get; set;}
public virtual Link Link {get; set;}
}
In my scenario, I can have a Link object where FirstLink and/or SecondLink can be null, references to other objects, or references to the same object.
Now I want to load an OtherObject entity from the db using EF. I load the entity itself and also the Link object associated with it. This is done perfectly by EF.
In this particular case, both FirstLink and SecondLink are the same as Link, therefore, when automapping from model to dto it just keeps on mapping into oblivion.
My mapping is:
Mapper.CreateMap<OtherObject, OtherObjectDto>().Bidirectional()
.ForMember(model => model.LinkId, option => option.Ignore());
where Bidirectional() is this extension:
public static IMappingExpression<TDestination, TSource> Bidirectional<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
return Mapper.CreateMap<TDestination, TSource>();
}
Is there way to tell Automapper not to map further down the tree in this case?
The way I would handle this is to create separate DTO objects for the children:
public class Employee
{
public int Id {get; set;}
public string Name { get; set; }
public Employee Supervisor {get; set; }
}
public class EmployeeDto {
public int Id {get; set;}
public string Name { get; set; }
public SupervisorDto Supervisor { get; set; }
public class SupervisorDto {
public int Id {get; set;}
public string Name { get; set; }
}
}
Mapper.CreateMap<Employee, EmployeeDto>();
Mapper.CreateMap<Employee, EmployeeDto.SupervisorDto>();
Don't let your DTOs be recursive/self-referential. Be explicit in your structure on how deep you want it to go.
EF can't do recursive joins, you're only doing one level, so don't make your DTOs go nuts with infinitely deep relationships. Be explicit.
I am currently working with a DB table and I need to map extra properties from DAO to BE class.
I have to produce XML like the following:
<Zoos>
<Zoo>
<ZooId>234OI456<ZooId>
<Name>The Zoo</Name>
<Address>3456 Kramer</Address
<ZipCode></ZipCode>
<Animals>
<Animal Type="REPTILE">Cobra</Animal>
<Animals>
<Zoo>
<Zoos>
The extra columns in the db view are like so:
ANI_TYPE VARCHAR(20)
ANI_VALUE VARCHAR(20)
Previously when I didn't have the extra columns I mapped the values like this for each Zoo
Mapper.CreateMap<ZooDAO, ZooBE>()
.ForMember(d => d.ZooId, e => e.ZOO_ID))
.ForMember(d => d.Name, e => e.ZOO_NAME))
.ForMember(d => d.Address, e => e.ZOO_ADDRESS))
.ForMember(d => d.ZipCode, e => e.ZOO_ZIPCODE));
How would I go about mapping these 2 columns(ANI_TYPE, ANI_VALUE) so i can create the structure shown in the xml in regards to Animals?
I have a c# class for Animal type which has the following
public enum AnimalType
{
INVALID,
REPTILE,
MAMMAL,
INSECT
}
My C# class for the Animal looks like this but i guess it will require rework. Feel free to provide suggestions/examples:
Currently this is what my classes look like:
//BE class
public class Zoo
{
public int ZooId {get; set;}
public string Name { get; set; }
public string Address {get; set; }
public string ZipCode {get; set;}
public List<Animal> Animals {get; set;}
}
//BE Class
public class Animal
{
public string Type {get; set;}
public string Text { get; set; }
}
My DAO class
public class ZooDAO
{
public int ZOO_ID {get; set;}
public string ZOO_NAME { get; set; }
public string ZOO_ADDRESS {get; set; }
public string ZOO_ZIPCODE {get; set;}
public string ANI_TYPE {get; set;}
public string ANI_VALUE {get; set;}
}
I appreciate if someone can assist me with the above.
Thanks,