I have the following DTO:
public class QuestionGroupDTO : IBaseDTO
{
public string Description { get; set; }
public string Header { get; set; }
public Guid Id { get; set; }
public int Order { get; set; }
public IEnumerable<Services.Forms.Models.RelationForm_QuestionGroupDTO> RelationForms_QuestionGroups { get; set; }
public IEnumerable<RelationQuestionGroup_QuestionDTO> RelationQuestionGroups_Questions { get; set; }
}
I have problem with the RelationQuestionGroups_Questions while converting.
Here Is how my RelationQuestionGroup_QuestionDTO looks like
public class RelationQuestionGroup_QuestionDTO
{
public int Order { get; set; }
[Required]
public Guid QuestionGroupId { get; set; }
[Required]
public Guid QuestionId { get; set; }
public virtual QuestionGroupDTO QuestionGroup { get; set; }
public virtual QuestionDTO Question { get; set; }
}
Here Is how I convert:
public static QuestionGroupDTO ToDTO(this QuestionGroup src)
{
var dto = new QuestionGroupDTO
{
Id = src.Id,
Header = src.Header,
Description = src.Description,
RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions.ToList()
};
return dto;
}
As you can see, I'm trying to just assign It and make a list of It, but I got a casting error here. I'm not sure how to do this.
I get the following error:
Cannot implicity convert type Generic List to System.Collections.Generic.IEnumerble
You're having a great start at mapping, but at RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions.ToList(), you're trying to assign a List<Entity> to List<Dto>. You can't do that.
You need to map any non-primitive properties as well. You can do that like this:
public static QuestionGroupDTO ToDTO(this QuestionGroup src)
{
var dto = new QuestionGroupDTO
{
// ...
RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions
.Select(ToDTO)
.ToList()
};
return dto;
}
Then you add a method to map RelationQuestionGroups_Question to RelationQuestionGroups_QuestionDTO:
public RelationQuestionGroups_QuestionDTO ToDTO(RelationQuestionGroups_Question entity)
{
return new RelationQuestionGroups_QuestionDTO
{
Order = entity.Order,
// ...
};
}
And then you'll go look at AutoMapper to automate this.
You forgot to map RelationQuestionGroups_Questions to RelationQuestionGroup_QuestionDTO.
public static QuestionGroupDTO ToDTO(this QuestionGroup src)
{
var dto = new QuestionGroupDTO
{
Id = src.Id,
Header = src.Header,
Description = src.Description,
RelationQuestionGroups_Questions = src.RelationQuestionGroups_Questions.Select(rq => new RelationQuestionGroup_QuestionDTO
{
Order = rq.Order,
QuestionGroupId = rq.QuestionGroupId,
QuestionId = rq.QuestionId
}).ToList()
};
return dto;
}
Related
Hi have a problem with auomapper where i try to use the Automapper.Mapper(src, dest) without loosing the values in the dest after doing the mapping.
I have a class which has a list of objects like below
public class UpdateShipmentDetailDto
{
public bool IsDocument { get; set; }
public List<UpdateItemDetailDto> ItemDetails { get; set; } = new();
}
which i want to map to
public class SCS_OUT_Manifest
{
public Guid ManifestId { get; set; }
public ICollection<SCS_OUT_ManifestItem> SCS_OUT_ManifestItems { get; set; } = new List<SCS_OUT_ManifestItem>();
}
The UpdateItemDetailDto class looks like this
public class UpdateItemDetailDto
{
public Guid ItemId { get; set; }
public string ItemDescription { get; set; }
public int Qty { get; set; }
public Guid UnitsId { get; set; }
public decimal ItemValue { get; set; }
}
And the SCS_OUT_ManifestItem class looke like
public class SCS_OUT_ManifestItem
{
public Guid ItemId { get; set; }
public Guid ManifestId { get; set; }
public string ItemDescription { get; set; }
public int Qty { get; set; }
public Guid UnitsId { get; set; }
public decimal ItemValue { get; set; }
}
Im performing a maaping like below, which map from ItemDetails (which is a list) to SCS_OUT_ManifestItems (which is also a ICollection).
_mapper.Map(updateShipmentDetailDto.ItemDetails, manifest.SCS_OUT_ManifestItems);
The problem after mapping is done the properties which in the destination collection are set to the default values.
for example the ManifestId inthe SCS_OUT_ManifestItem manifest.SCS_OUT_ManifestItems which is not in updateShipmentDetailDto.ItemDetails is set to its default Guid value 00000000-0000-0000-0000-000000000000.
But if i run this in a loop like below it works.
foreach (var item in manifest.SCS_OUT_ManifestItems)
{
_mapper.Map(updateShipmentDetailDto.ItemDetails.Single(s => s.ItemId == item.ItemId), item);
}
Please help! thanks in advance
Try map your lists and your itens and use the same name ÏtemDetails" in both lists.
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<UpdateItemDetailDto, SCS_OUT_ManifestItem>();
cfg.CreateMap<UpdateShipmentDetailDto, SCS_OUT_Manifest>();
});
var _mapper = config.CreateMapper();
var updateShipmentDetailDto = new UpdateShipmentDetailDto();
var updateItemDetailDto = new UpdateItemDetailDto();
var manifest = new SCS_OUT_Manifest();
updateItemDetailDto.ItemId = Guid.NewGuid();
updateItemDetailDto.UnitsId = Guid.NewGuid();
manifest.ManifestId = Guid.NewGuid();
updateItemDetailDto.ItemDescription = "test";
updateItemDetailDto.Qty = 10;
updateItemDetailDto.ItemValue = 25.50M;
updateShipmentDetailDto.ItemDetails = new List<UpdateItemDetailDto>();
updateShipmentDetailDto.ItemDetails.Add(updateItemDetailDto);
_mapper.Map(updateShipmentDetailDto.ItemDetails, manifest.ItemDetails);
Console.WriteLine($"DTO Guid: {updateShipmentDetailDto.ItemDetails[0].ItemId}, Desc: {updateShipmentDetailDto.ItemDetails[0].ItemDescription}");
foreach (var item in manifest.ItemDetails)
{
Console.WriteLine($"Guid: {item.ItemId}, Desc: {item.ItemDescription}");
}
Console.WriteLine($"Guid Manifest: {manifest.ManifestId}");
I'm actually using EF and very new to it. I have a EDMX-Model from Database. I have to get a List of Entities, but in this Table is Binary-Column. I want my Object-List from that Table without the Binary Data.
My Entity-Objekt looks like:
public partial class bons
{
public int id { get; set; }
public System.DateTime zeitstempel { get; set; }
public byte[] bonBinaer { get; set; }
public Nullable<int> tisch_nr { get; set; }
public bool abgearbeitet { get; set; }
public int kunde_id { get; set; }
public string hash { get; set; }
public string dateiname { get; set; }
public string tisch_name { get; set; }
public int gang { get; set; }
public decimal brutto { get; set; }
public Nullable<System.DateTime> zeitstempelAbgearbeitet { get; set; }
public Nullable<int> positionenAnzahl { get; set; }
public bool manuell { get; set; }
}
And I#m getting the List like:
internal static List<bons> holeBongListeNichtAbgearbeitetRestaurant(int kunde_id)
{
List<bons> rückgabe = new List<bons>();
using (bonsEntities context = new bonsEntities())
{
rückgabe = context.bons.Where(x => x.kunde_id == kunde_id && x.abgearbeitet == false).OrderBy(x => x.zeitstempel).ToList();
}
return rückgabe;
}
Can someone help how to get the List without the 'byte[] bonBinaer'?
Hi you can use autoMapper with EF extension
like: https://docs.automapper.org/en/stable/Queryable-Extensions.html
or if you prefer you can do by yourself with a Select() method like:
using (bonsEntities context = new bonsEntities())
{
rückgabe = context.bons.Where(x => x.kunde_id == kunde_id && x.abgearbeitet == false).OrderBy(x => x.zeitstempel).Select(xx=> new {
id = xx.id
//and all you props
}).ToList().Select(yy=> new bons{
id=yy.id
//and back with other props
}).ToList();
}
How can i fix Cannot implicitly convert System.Collections.Generic.List <RPHistory> to System.Collections.Generic.List <RPHistory> exception error.
I am trying to combine two Entities together to get a single list
RP Entity Class:
public class RP
{
public int ID { get; set; }
public int RPID { get; set; }
public string Name { get; set; }
public int ProductID { get; set; }
}
RPHistory Entity Class :
public class RPHistory:
{
public int ID { get; set; }
public int RPID { get; set; }
public string Name { get; set; }
public int ProductID { get; set; }
}
And I created this third class
RpWithHistory Class :
public class RpWithHistory {
public int ID;
public int RPID;
public string Name;
public int ProductID;
public List<RPHistory> History;
}
Linq Query
var RPs = await Context.RP.Where(b => b.ProductID == request.ID)
.Select(x=> new RpWithHistory {
ID = x.ID,
RPID = x.RPID,
Name = x.Name,
ProductID = x.ProductID,
History = Context.RPHistory
.Where(y=> y.RPID
== x.RPID)
.ToList()
}
).ToListAsync();
But i get this error,
>Cannot implicitly convert System.Collections.Generic.List <RPHistory> to
>System.Collections.Generic.List <RPHistory> exception error
Thanks!
I am not sure why you're doing that. Can I suggest this?
You do not need to go all that way of creating a class that joins the two. Just create a Navigation property on your RP that points to RPHistory Objects.
public class RP
{
public int ID { get; set; }
public int RPID { get; set; }
public string Name { get; set; }
public int ProductID { get; set; }
public ICollection<RPHistory> HistoryList { get; set; } // Navigation Property
}
public class RPHistory:
{
public int ID { get; set; }
public int RPID { get; set; }
public string Name { get; set; }
public int ProductID { get; set; }
[ForeignKey(nameof(RPID))] // Identify the Foreign Key from RP Class
public RP RP { get; set; } // Navigation back to RP
}
Then you can chain everything into a single list using LINQ:
var RPs = Context.RP.Where(rp => rp.ProductID == request.ID)
.Include(rp=>rp.RPHistory) // This includes RPHistory
.ToList();
You need to clone or create a new list.
Option 1: Use ConvertAll
List<RPHistory> pPHistoryCopy = rphWithHistory.RPHistory.ConvertAll(history => new RPHistory(rphWithHistory.RPHistory));
Option 2:
//Clone Extension
static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
}
Use the clone extention
I am trying to map from my webapi to my solution some ICollection
this is a HttpClient: var currentNotifications = await client.GetUsersAsync();
If I have a model for example:
public class UserNotificationTypeDeliveryChoice
{
public DeliveryType DeliveryType { get; set; }
public NotificationGroup NotificationGroup{ get; set; }
}
public class DeliveryType
{
public byte DeliveryTypeId { get; set; }
public string Name { get; set; }
}
public class NotificationGroup
{
public byte NotificationGroupId { get; set; }
public string Name { get; set; }
}
and model to map to:
public class NotificationListViewModel
{
public DeliveryType DeliveryType { get; set; }
public NotificationGroup NotificationGroup { get; set; }
}
public class DeliveryType
{
public byte DeliveryTypeId { get; set; }
public string Name { get; set; }
}
public class NotificationGroup
{
public int NotificationGroupId { get; set; }
public string Name { get; set; }
}
So, I have an ICollection<UserNotificationTypeDeliveryChoice> currentNotifications from my webapi which I need to map to
List<NotificationListViewModel> notificationListViewModel
Myexample looks like:
var res = currentNotifications.ToList().ForEach(x => notificationListViewModel.Add(new NotificationListViewModel()
{
DeliveryType = new DeliveryType() {DeliveryTypeId = x.DeliveryType.DeliveryTypeId.Value, Name = x.DeliveryType.Name },
NotificationGroup = new NotificationGroup() { NotificationGroupId = x.NotificationGroup.NotificationGroupId.Value, Name = x.NotificationGroup.Name }
}));
But, it reports me an error: CS0815 Cannot assign void to an implicitly-typed variable
Ofc, if you have better solution, without ForEach I would be thankful.
ForEach() does not return anything.
You could do it with a Select() call instead:
var result = currentNotifications.Select(x => new NotificationListViewModel
{
DeliveryType = new DeliveryTypeViewModel
{
DeliveryTypeId = x.DeliveryType.DeliveryTypeId,
Name = x.DeliveryType.Name
},
NotificationGroup = new NotificationGroupViewModel
{
NotificationGroupId = x.NotificationGroup.NotificationGroupId,
Name = x.NotificationGroup.Name
}
});
I added ViewModel suffix to all view model class names to make it more readable.
The issue is here:
var res = currentNotifications.ToList().ForEach(...);
ForEach() returns void and therefore you're trying to assign void to res. That doesn't work.
First store the list, then do the ForEach:
var res = currentNotifications.ToList();
res.ForEach(...);
Or simply drop the res altogether, since you're storing the outcome in notificationListViewModel anyway.
currentNotifications.ToList().ForEach(...);
It depends on whether you still need res or not.
As an aside and further improvement, you're doing a LINQ Select() in a different way. Using the LINQ equivalent:
notificationListViewModel = currentNotifications.Select(x => new NotificationListViewModel() { ... });
Hi I am new to entity framework. I have following objects
public partial class lr
{
public lr()
{
this.lr_history = new HashSet<lr_history>();
this.people = new HashSet<person>();
}
public int _id { get; set; }
public string name { get; set; }
public string notes { get; set; }
public virtual ICollection<lr_history> lr_history { get; set; }
public virtual ICollection<person> people { get; set; }
In my Web Api controller I have following code
public class lrController : ApiController
{
private CTM db = new CTM();
// GET api/addL
public IEnumerable<lr> Getlr()
{
from a in DbContext.Activities
return db.lr.AsEnumerable();
}
In above Get method it returns lr but i want to return my own object like
lr.id
lr.name
lr_history.description
lrh_history.rate
Can anyone show me how to achieve this? Than
Create a new model:
class HistoryModel
{
public int Id { get; set; }
public string Name { get; set; }
public string HistoryDescription { get; set; }
public string HistoryRate { get; set; }
}
and return that:
public IEnumerable<HistoryModel> Getlr()
{
from a in DbContext.Activities
return db.lr.AsEnumerable()
.Select(x => new HistoryModel
{
Id = x.id,
Name = x.name,
HistoryDescription = x.history.description,
HistoryRate = x.history.rate
});
}
Instade of return db.lr.AsEnumerable();
try this
return db.lr.ToList();