MVC models converting error - asp.net-mvc

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.

Related

AutoMapper Many to Many relationship

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>();

NullReferenceException in a three table model in Entity Framework

I'm trying to join three tables in a view model. It works with two tables but crashes when I add a third. Here are the models and the controller. The models section_detail, phone, and department were generated by Entity Framework.
EmployeeViewModel was created by copying properties from the other models. I've abbreviated some of the models shown here with:
public partial class section_detail
{
public int section_detail_id { get; set; }
public Nullable<int> parent_section_det_id { get; set; }
. . .
public string Comments { get; set; }
public string email { get; set; }
public virtual department department { get; set; }
public virtual phone phone { get; set; }
}
public partial class phone
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public phone()
{
this.section_detail = new HashSet<section_detail>();
}
public int phone_id { get; set; }
public string area_code { get; set; }
public string phone_nbr { get; set; }
. . .
public string activity_code { get; set; }
public string function_code { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<section_detail> section_detail { get; set; }
public virtual BudgetUnit BudgetUnit { get; set; }
}
public partial class department
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public department()
{
this.section_detail = new HashSet<section_detail>();
}
public int dept_id { get; set; }
public string description { get; set; }
public string cost_center_code { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<section_detail> section_detail { get; set; }
}
public class EmployeeViewModel
{
public int section_detail_id { get; set; }
public Nullable<int> parent_section_det_id { get; set; }
public Nullable<byte> page_code { get; set; }
public string cost_center_code { get; set; }
public string print_descrip { get; set; }
public Nullable<int> phone_id { get; set; }
public Nullable<int> employee_id { get; set; }
public static explicit operator EmployeeViewModel(List<section_detail> v)
{
throw new NotImplementedException();
}
public string first_name { get; set; }
. . .
public string Comments { get; set; }
public string email { get; set; }
public string description { get; set; }
public string area_code { get; set; }
public string phone_nbr { get; set; }
public string BU { get; set; }
}
Controller:
private vcpds_test1Entities db = new vcpds_test1Entities();
// GET: EmployeeList
public ActionResult Index()
{
List<section_detail> employeeList = db.section_detail.ToList();
List<EmployeeViewModel> employeeVMList = employeeList.Where(emp => emp.page_code == 3)
.Select(emp => new EmployeeViewModel
{
last_name = emp.last_name,
first_name = emp.first_name,
employee_id = emp.employee_id,
phone_nbr = "(" + emp.phone.area_code + ") " + emp.phone.phone_nbr.Substring(0, 3) + "-" + emp.phone.phone_nbr.Substring(3, 4),
BU = emp.phone.BU,
description = emp.department.description,
page_code = emp.page_code
}).OrderBy(emp => emp.last_name).ThenBy(emp => emp.first_name).ToList();
return View(employeeVMList);
}
I get these messages:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
VCPDS2.Models.section_detail.department.get returned null.
If I comment out description = emp.department.description from the controller, then it will return data from the section_detail and phone tables. I've checked the database and the relationships seem ok. I've tried refreshing the models from the database with no change.
It's possible that a emp doesn't have a department so it in itself is null. Description can't be a property of a null. So, what you can simply do is check if it is null first by using null operator:
...
//description = emp.department.description,
description = emp.department?.description ?? "",
...
Basically, if department itself is null, it will stop checking right there, and the ?? shortcut is to use the statement on the right side which is "" if the statement on the left is null.
If you were not expecting an emp not to have a department, you may need to revise your query
Quick edit: You probably need to use an Include in your query so it can bring the department's properties (for description):
List<section_detail> employeeList = db.section_detail
.Include(x => x.department)
.ToList();

Xamarin.ios - Using NBuilder to build mocks throws TypeCreationException

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)])

Automapper mapping issue

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));

Linq doesn't want to cooperate - DbExpressionBinding error

I am trying to get something from my database, i need it to be like that:
var tribunalCase = context.TribunalCases.Where(c => c.Voters.Any(v => v.Voter.UserName == User.Identity.Name))
.Select(c => c)
.ToList();
But then, it crashes when i try to use .Any() or .All(). I get the following error:
DbExpressionBinding requires an input expression with a collection
ResultType.
Parameter name: input
This is my model:
public class Tribunal
{
public int Id { get; set; }
public Account User { get; set; }
public DateTime Expires { get; set; }
public Thread Thread { get; set; }
public int Points { get; set; }
public String Comment { get; set; }
public int VotersCount { get; set; }
public List<Voters> Voters { get; set; }
}
public class Voters
{
public int Id { get; set; }
public Account Voter { get; set; }
public bool Vote { get; set; }
public Tribunal Tribunal { get; set; }
}
Which i configured like that:
modelBuilder.Entity<Tribunal>()
.HasOptional(t => t.Voters)
.WithRequired();
How can i fix this error?
Configuration is incorrect: Voters is a collection, so you should call HasMany, not HasOptional.

Resources