I need to map a model to a viewmodel using AutoMapper.
Model:
[Table("News")]
public class News
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public DateTime DatePostedOn { get; set; }
public int Position { get; set; }
public Category Category { get; set; }
public virtual ICollection<Picture> Pictures { get; set; }
}
[Table("Pictures")]
public class Picture
{
[Key]
public int Id { get; set; }
public DateTime DateCreated { get; set; }
public string Filename { get; set; }
public int Type { get; set; }
public virtual ICollection<News> News { get; set; }
}
Viewmodel:
public class HomeViewModels
{
public IList<HomeMainNews> MainNews { get; private set; }
}
public class HomeMainNews
{
public int Id { get; set; }
public string Title { get; set; }
public string Date { get; set; }
public string PictureURL { get; set; }
}
Mapping:
Mapper.CreateMap<News, HomeMainNews>();
How can I map a News that have a set of Pictures, to a viewmodel with only one picture according to a certain condition "Type = 2"
Current solution:
vm.MainNews = db.News
.Select(n => new HomeMainNews {
Id = n.Id,
Date = n.DatePostedOn.ToString(),
Title = n.Title,
PictureURL = n.Pictures.Where(p => p.Type == 1).Select(p => p.Filename).FirstOrDefault().ToString()
}).ToList();
Automapper solution:
vm.MainNews = db.News.Project().To<HomeMainNews>().ToList();
Try this
Mapper.CreateMap<News, HomeMainNews>()
.ForMember(mainNew => mainNew.Date, opt => opt.MapFrom(news => news.DatePostedOn))
.ForMember(mainNew => mainNew.PictureURL, opt => opt.MapFrom(news => news.Pictures.First(pic => pic.Type == 2).Filename));
Related
I'm not sure where I'm going wrong here. I want to map my classes so that there aren't extra levels in the returned values.
Models (DTOs):
public class FilmViewModel
{
public FilmViewModel() { }
public int Id { get; set; }
[Required(ErrorMessage = "Naziv filma je obavezno polje.")]
public string Naziv { get; set; }
public string Opis { get; set; }
public string UrlFotografije { get; set; }
[RegularExpression(#"^(19|20)[\d]{2,2}$", ErrorMessage = "Godina mora biti u YYYY formatu.")]
public int Godina { get; set; }
public JezikEnum Jezik { get; set; }
public int Trajanje { get; set; }
public bool IsActive { get; set; }
public List<Licnost> Licnosti { get; set; }
}
public class LicnostViewModel
{
public LicnostViewModel() { }
public int Id { get; set; }
[Required]
public string ImePrezime { get; set; }
[Required]
public bool IsGlumac { get; set; }
[Required]
public bool IsRedatelj { get; set; }
public List<Film> Filmovi { get; set; }
}
Entities:
public class Film
{
[Key]
public int Id { get; set; }
[Required]
public string Naziv { get; set; }
public string Opis { get; set; }
public string UrlFotografije { get; set; }
[RegularExpression(#"^(19|20)[\d]{2,2}$")]
public int Godina { get; set; }
public JezikEnum Jezik { get; set; }
public bool IsActive { get; set; }
public int Trajanje { get; set; }
public List<FilmLicnost> Licnosti { get; set; }
}
public class Licnost
{
[Key]
public int Id { get; set; }
[Required]
public string ImePrezime { get; set; }
[Required]
public bool IsGlumac { get; set; }
[Required]
public bool IsRedatelj { get; set; }
public List<FilmLicnost> Filmovi { get; set; }
}
public class FilmLicnost
{
[Key]
public int Id { get; set; }
[ForeignKey(nameof(Licnost))]
public int LicnostId { get; set; }
public Licnost Licnost { get; set; }
[ForeignKey(nameof(Film))]
public int FilmId { get; set; }
public Film Film { get; set; }
}
Basically Swagger already shows me what I'm returning, but I want to avoid unnecessary nesting. It's marked in the image:
I want to say that I've been looking all over SO, AutoMapper documentation etc. No answer/example finds me the solution I need. I'm either missing a Model(DTO) somewhere or there is something major wrong with my logic.
Some example links that I tried are this and this
Also here are some links I tried to get information from: link1, link2
This is what I've tried so far:
CreateMap<FilmLicnost, LicnostViewModel>()
.ForMember(dest => dest.Filmovi, dest => dest.MapFrom(x => x.Film))
.AfterMap((source, destination) =>
{
if (destination?.Filmovi == null) return;
foreach (var temp in destination.Filmovi)
{
temp.Id = source.Film.Id;
temp.IsActive = source.Film.IsActive;
temp.Jezik = source.Film.Jezik;
temp.Naziv = source.Film.Naziv;
temp.Opis = source.Film.Opis;
temp.Godina = source.Film.Godina;
temp.Trajanje = source.Film.Trajanje;
temp.UrlFotografije = source.Film.UrlFotografije;
}
});
CreateMap<FilmLicnost, FilmViewModel>()
.ForMember(dest => dest.Licnosti, dest => dest.MapFrom(x => x.Licnost))
.AfterMap((source, destination) =>
{
if (destination?.Licnosti == null) return;
foreach (var temp in destination?.Licnosti)
{
temp.Id = source.Licnost.Id;
temp.ImePrezime = source.Licnost.ImePrezime;
temp.IsGlumac = source.Licnost.IsGlumac;
temp.IsRedatelj = source.Licnost.IsRedatelj;
}
});
Also this:
CreateMap<FilmLicnost, Film>()
.ForMember(dest => dest.Licnosti, dest => dest.Ignore());
CreateMap<FilmLicnost, Licnost>()
.ForMember(dest => dest.Filmovi, dest => dest.Ignore());
Note I have already defined the mapping for Entities:
CreateMap<Film, FilmViewModel>();
CreateMap<FilmViewModel, Film>();
CreateMap<Licnost, LicnostViewModel>();
CreateMap<LicnostViewModel, Licnost>();
I'm quite new to ASP.NET MVC. I am creating a holiday tracking app, and I'm attempting to create a details page for each Employee. I want this page to display a table showing a table of all the holiday request that employee has taken. I've gotten it to work but it only shows only one row.
Here's my models
public partial class Employee
{
public int EmployeeID { get; set; }
public string FullName { get; set; }
public string EmailID { get; set; }
public string Password { get; set; }
public System.DateTime StartDate { get; set; }
public int RoleID { get; set; }
public int ShiftID { get; set; }
public int AreaID { get; set; }
public int DisciplineID { get; set; }
public int SiteID { get; set; }
public int ALCategory { get; set; }
public Nullable<int> HoursTaken { get; set; }
public Nullable<int> AwardedLeave { get; set; }
public Nullable<int> TotalHoursThisYear { get; set; }
public int HoursCarriedForward { get; set; }
public Nullable<int> EntitlementRemainingThisYear { get; set; }
public string Comments { get; set;}
}
Employee Model:
public class EmployeeViewModel
{
public Employee Employee { get; set; }
public HolidayRequestForm HolidayRequestForm { get; set; }
}
Holiday Request Form Model:
public partial class HolidayRequestForm
{
public int RequestID { get; set; }
public int EmployeeID { get; set; }
public System.DateTime StartDate { get; set; }
public System.DateTime FinishDate { get; set; }
public int HoursTaken { get; set; }
public string Comments { get; set; }
public int YearCreated { get; set; }
public int MonthCreated { get; set; }
public Nullable<int> DayCreated { get; set; }
public Nullable<int> YearOfHoliday { get; set; }
public virtual Employee Employee { get; set; }
}
Controller Action:
public ActionResult Details(int? id)
{
Employee employee = db.Employees.FirstOrDefault(emp => emp.EmployeeID == id);
HolidayRequestForm holidayRequestForm db.HolidayRequestForms.FirstOrDefault(emp => emp.EmployeeID == id);
EmployeeViewModel employeeViewModel = new EmployeeViewModel()
{
Employee = employee,
HolidayRequestForm = holidayRequestForm,
};
return View(employeeViewModel);
}
My View is then just a HTML table to display the data from the database.
So the question is how do I display more than one row or entry?? Is it that I'm using FirstorDefault?
You must change Employee Model and declare a list for the Holiday :
Employee Model:
public class EmployeeViewModel
{
public Employee Employee { get; set; }
public List<HolidayRequestForm> HolidayRequestForm { get; set; }
}
Controller Action:
public ActionResult Details(int? id)
{
Employee employee = db.Employees.FirstOrDefault(emp => emp.EmployeeID == id);
List<HolidayRequestForm> holidayRequestForm = db.HolidayRequestForms.Where(emp => emp.EmployeeID == id).ToList();
EmployeeViewModel employeeViewModel = new EmployeeViewModel()
{
Employee = employee,
HolidayRequestForm = holidayRequestForm,
};
return View(employeeViewModel);
}
I'm using the NBuilder library to build mock http responses, everything works fine in Android, but in iOS each time that I want to build a model class this exception is fired.
"FizzWare.NBuilder.TypeCreationException" and It says that my X model class doesn't have a parametless constructor, which actually has!. For example this model class:
public class Actor
{
public Actor() {
}
[JsonProperty("authorities")]
public List<Authority> Authorities { get; set; }
[JsonProperty("imageDerivatives")]
public ImageDerivatives ImageDerivatives { get; set; }
[JsonProperty("profileFileId")]
public PictureFile ProfilePicture { get; set; }
[JsonProperty("role")]
public Role Role { get; set; }
[JsonProperty("roleId")]
public int RoleId { get; set; }
[JsonProperty("status")]
public bool Status { get; set; }
[JsonProperty("updatedAt")]
public DateTime UpdatedAt { get; set; }
[JsonProperty("username")]
public string Username { get; set; }
[JsonProperty("createdAt")]
public DateTime CreatedAt { get; set; }
[JsonProperty("departmentId")]
public int DepartmentId { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("firstName")]
public string FirstName { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("isAppAdmin")]
public bool IsAppAdmin { get; set; }
[JsonProperty("lastName")]
public string LastName { get; set; }
[JsonProperty("password")]
public string Password { get; set; }
}
And this is how I build the mock response:
private Actor GetRandomActor()
{
return Builder<Actor>.CreateNew()
.With(a => a.FirstName = GetRandomFirstName())
.With(a => a.LastName = GetRandomLastName())
.With(a => a.ProfilePicture = GetRandomPictureFile())
.With(a => a.Email = GetRandomEmail())
.With(a => a.Username = GetRandomUserName())
.Build();
}
Try adding the Preserve attribute to your constructor so it does not get removed by the Linker:
[Preserve]
public Actor() {}
(Or add it at the class level [Preserve (AllMembers = true)])
How to set to a different model?
List<ORDER_DETAILSMetadata> result = db.ORDER_DETAILS.Where(p => p.Order_Number == id).ToList();
Error 6 Cannot implicitly convert type 'System.Collections.Generic.List<Mvc5.Models.ORDER_DETAILS>' to 'System.Collections.Generic.List<Mvc5.Models.ORDER_DETAILSMetadata>'
ORDER_DETAILSMetadata
MetadataType(typeof(ORDER_DETAILSMetadata))]
public partial class ORDER_DETAILS
{
// Note this class has nothing in it. It's just here to add the class-level attribute.
}
public class ORDER_DETAILSMetadata
{
public int Order_Details_ID { get; set; }
public Nullable<int> Order_Number { get; set; }
public Nullable<short> Sequence_Number { get; set; }
public string Item_Num { get; set; }
public Nullable<short> Order_Quantity { get; set; }
public Nullable<short> Ship_Quantity { get; set; }
}
ORDER_DETAILS.cs
public partial class ORDER_DETAILS
{
public int Order_Details_ID { get; set; }
public Nullable<int> Order_Number { get; set; }
public Nullable<short> Sequence_Number { get; set; }
public string Item_Num { get; set; }
public Nullable<short> Order_Quantity { get; set; }
public Nullable<short> Ship_Quantity { get; set; }
}
As far as i have understood, you can do something like this:
List<ORDER_DETAILSMetadata> result = db.ORDER_DETAILS.
Where(p => p.Order_Number == id).
Select(x => new ORDER_DETAILSMetadata
{
Order_Details_ID = x.Order_Details_ID,
Order_Number = x.Order_Number,
Sequence_Number = x.Sequence_Number,
Item_Num = x.Item_Num,
Order_Quantity = x.Order_Quantity,
Ship_Quantity = x.Ship_Quantity
}).ToList();
If you just want to convert one type of model to other type, you can do something like:
List<target> targetList = new List<target>(originalList.Cast<target>());
You can check the details about Cast() and OfType() here. Go for the first approach when you have different count and types of fields.
I'm learning ASP.NET MVC 4 with Entity Framework (Database First) and ran into a problem that I'm not able to solve.
I have following tables:
Student: To store students information
Course: To store courses running in an institute
StudentCourse: To store which student selected what course
Fees: To store submitted fees by a student corresponding to StudentCourse
Now, I wan't to show course name, course fees, total fees submitted & the pending fees of students
I'm using Entity Framework in the project and trying to execute a query like this:
var feeslist = entities.Fees
.Where(m => m.StudentCourse.status=="pending")
.GroupBy(m => m.StudentCourse.id)
.Select(m => new { StudentCourseId = m.Key, SumOfFees = m.Sum(v => v.fees) });
I want to get Course object instead of StudentCourseId so that i can display the course, its course fees and total fees submitted by student.
In case, I'm listing all of the four class contents:
Student
public partial class Student
{
public Student()
{
this.Leaves = new HashSet<Leave>();
this.StudentCourses = new HashSet<StudentCourse>();
}
public int id { get; set; }
public string first_name { get; set; }
public string middle_name { get; set; }
public string last_name { get; set; }
public string password { get; set; }
public string email { get; set; }
public string gender { get; set; }
public string facebook { get; set; }
public string contact_number { get; set; }
public string address { get; set; }
public string admin { get; set; }
public string college { get; set; }
public string status { get; set; }
public System.DateTime createdat { get; set; }
public System.DateTime updatedat { get; set; }
public string descripton { get; set; }
public virtual ICollection<Leave> Leaves { get; set; }
public virtual ICollection<StudentCourse> StudentCourses { get; set; }
}
Course
public partial class Course
{
public Course()
{
this.CourseContents = new HashSet<CourseContent>();
this.StudentCourses = new HashSet<StudentCourse>();
}
public int id { get; set; }
public string course_name { get; set; }
public int course_fees { get; set; }
public int duration { get; set; }
public string admin { get; set; }
public string status { get; set; }
public System.DateTime createdat { get; set; }
public System.DateTime updatedat { get; set; }
public virtual ICollection<CourseContent> CourseContents { get; set; }
public virtual ICollection<StudentCourse> StudentCourses { get; set; }
}
StudentCourse
public partial class StudentCourse
{
public StudentCourse()
{
this.Fees1 = new HashSet<Fee>();
this.Issues = new HashSet<Issue>();
}
public int id { get; set; }
public int student_id { get; set; }
public int course_id { get; set; }
public int fees { get; set; }
public System.DateTime join_date { get; set; }
public string admin { get; set; }
public System.DateTime createdat { get; set; }
public System.DateTime updatedat { get; set; }
public string status { get; set; }
public virtual Course Course { get; set; }
public virtual ICollection<Fee> Fees1 { get; set; }
public virtual ICollection<Issue> Issues { get; set; }
public virtual Student Student { get; set; }
}
Fee
public partial class Fee
{
public int id { get; set; }
public int student_course_id { get; set; }
public int fees { get; set; }
public string admin { get; set; }
public System.DateTime createdat { get; set; }
public System.DateTime updatedat { get; set; }
public virtual StudentCourse StudentCourse { get; set; }
}
var feeslist = entities.Fees
.Where(m => m.StudentCourse.status=="pending")
.GroupBy(m => m.StudentCourse.Course)
.Select(m => new { Course = m.Key, SumOfFees = m.Sum(v => v.fees) });