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}");
Related
I have an AcadamicFee list, at one point in time I want to insert an item under Fee. So that, it should add like Fee[1], Fee[2].modified the code like below.
I want to insert one new item under Fee list. But it didn't reflect. How to update the AcadamicFee list through Linq?
Thanks in advance.
AcadamicFee[0]
{
----
----
----
TermDetails [0]
{
---
Fee[0]
Fee[1]
Fee[2]
}
}
public class Fee
{
public int FeeID { get; set; }
public string FeeName { get; set; }
public string FeeAmount { get; set; }
public string IsFineApplicable { get; set; }
public string LastDate { get; set; }
}
public class Ter
{
public int TermID { get; set; }
public string TermName { get; set; }
public IEnumerable<Fee> FeeDetails { get; set; }
}
public class AcadamicFee
{
public int id { get; set; }
public string AdmissionID { get; set; }
public string StudentName { get; set; }
public int Class { get; set; }
public string AcadamicYear { get; set; }
public Nullable<int> TotalPaid { get; set; }
public Nullable<int> AcadamicAmount { get; set; }
public Nullable<int> BalanceAmount { get; set; }
public IEnumerable<Term> TermDetails { get; set; }
}
Any clue how to do with Linq? I tried something like this:
for (var i = 0; i < fees.Count; i++)
{
bool termDetailsExist = acadamic_fee.Any(a => a.TermDetails.Any(b => b.TermID == fees[i].TermID));
if (termDetailsExist)
{
foreach (AcadamicFeeModel acm in acadamic_fee)
{
foreach (TermModel trm in acm.TermDetails)
{
if (trm.TermID == fees[i].TermID)
{
List<FeeModel> FeeType = new List<FeeModel>();
FeeType.Add(new FeeModel
{
FeeID = fees[i].FeeID,
FeeName = fees[i].FeeName,
FeeAmount = fees[i].FeeAmount,
IsFineApplicable = fees[i].IsFineApplicable,
LastDate = fees[i].LastDate,
});
trm.FeeDetails.ToList().AddRange(FeeType);
}
}
}
}
}
trm.FeeDetails.ToList().AddRange(FeeType);
You've created a new List<FeeModel>, added a copy of the FeeDetails sequence, added a new FeeModel object, and then thrown the new list away.
You need to store the modified list in the property - for example:
foreach (TermModel trm in acm.TermDetails)
{
if (trm.TermID == fees[i].TermID)
{
List<FeeModel> FeeType = new List<FeeModel>();
FeeType.Add(new FeeModel
{
FeeID = fees[i].FeeID,
FeeName = fees[i].FeeName,
FeeAmount = fees[i].FeeAmount,
IsFineApplicable = fees[i].IsFineApplicable,
LastDate = fees[i].LastDate,
});
FeeType.AddRange(trm.FeeDetails);
trm.FeeDetails = FeeType;
}
}
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();
}
Here I have two list var userListFromFriendTable = mainService.GetUserFromFriend(ChattingUserName); and var getAllUserFromMessageUserTable = mainService.GetalluserfromMessageUser(); whose implementation are
given below.
Now what is want is to remove all the Friend table FriendRequestReceiverName column data of userListFromFriendTable list from MessageUser table MessageUserName column of getAllUserFromMessageUserTable list.
Any help will be grate
public List<Friend> GetUserFromFriend(string chattingUserName)
{
var checkUser = uow.Repository<Friend>().FindBy(x => x.FriendRequestSenderName.ToLower() == chattingUserName.ToLower()).ToList();
return checkUser;
}
public List<MessageUser> GetalluserfromMessageUser()
{
var checkUser = uow.Repository<MessageUser>().GetAll().ToList();
return checkUser;
}
public class Friend
{
public int FriendId { get; set; }
public string FriendRequestSenderName { get; set; }
public string FriendRequestReceiverName { get; set; }
public int IsConfirmed { get; set; }
}
public class MessageUser
{
public int Id { get; set; }
public string MessageUserName { get; set; }
public int IsFriend { get; set; }
}
try this:
var names=userListFromFriendTable.Select(i=> i.FriendRequestReceiverName)
.OfType<string>()
.ToArray();
getAllUserFromMessageUserTable.RemoveAll(r => names.Contains( r.MessageUserName );
I processing a soap response which the xml has a purchase order within items
eg
<PurchaseOrder>
<WHID>2</WHID>
<Supplier_ID>00</Supplier_ID>
<POID>6</POID>
<CreateDate>2013-01-02T10:48:27.37+11:00</CreateDate>
<CurrencyName>Australian Dollars</CurrencyName>
<ShippingStatus>Departed</ShippingStatus>
<payment_terms></payment_terms>
<shipping_terms></shipping_terms>
<POStatus>Back-Order</POStatus>
<PurchaseOrderItems>
<PurchaseOrderItem>
<SKU>Shoe30</SKU>
<Product_ID>124064</Product_ID>
<QtyOrdered>9</QtyOrdered>
<QtyOutstanding>6</QtyOutstanding>
<BuyPriceEx>20.0000</BuyPriceEx>
<DirectCosts>0.0000</DirectCosts>
<SupplierBuyPrice>20.0000</SupplierBuyPrice>
</PurchaseOrderItem>
</PurchaseOrderItems>
</PurchaseOrder>
I have no issues putting this into a jagged list . my classes look like this
public class PurchaseOrder
{
public string WHID { get; set; }
public string Supplier_ID { get; set; }
public string POID { get; set; }
public string CreateDate { get; set; }
public string CurrencyName { get; set; }
public string ShippingStatus { get; set; }
public string payment_terms { get; set; }
public string shipping_terms { get; set; }
public string POStatus { get; set; }
public List<PurchaseOrderItems> PurchaseOrderItems { get; set; }
}
public class PurchaseOrderItems
{
public string SKU { get; set; }
public string Product_ID { get; set; }
public string QtyOrdered { get; set; }
public string QtyOutstanding { get; set; }
public string BuyPriceEx { get; set; }
public string DirectCosts { get; set; }
public string SupplierBuyPrice { get; set; }
}
I fill the purchase order class using the following linq
List<PurchaseOrder> _orderDetailed = items.Select(po => new PurchaseOrder()
{
WHID = (string)po.Element("WHID").ElementValueNull(),
Supplier_ID = (string)po.Element("Supplier_ID").ElementValueNull(),
POID = (string)po.Element("POID").ElementValueNull(),
CreateDate = (string)po.Element("CreateDate").ElementValueNull(),
CurrencyName = (string)po.Element("CurrencyName").ElementValueNull(),
payment_terms = (string)po.Element("payment_terms").ElementValueNull(),
shipping_terms = (string)po.Element("shipping_terms").ElementValueNull(),
POStatus = (string)po.Element("POStatus").ElementValueNull(),
PurchaseOrderItems = po.Descendants("PurchaseOrderItem").Select(i => new PurchaseOrderItems()
{
SKU = (string)i.Element("SKU").ElementValueNull(),
Product_ID = (string)i.Element("Product_ID").ElementValueNull(),
QtyOrdered = (string)i.Element("QtyOrdered").ElementValueNull()
}).ToList()
}).ToList();
The problem come when I pass this to a reflection function that write the object to csv. it only writes the PurchaseOrder fields to the file. I have no idea how to access the PurchaseOrderItems fields so I can write them to the file.
I need to achieve the following using the above xml structure.
WHID Supplier_ID POID SKU Product_ID QtyOrdered
2 00 6 Shoe30 124064 6
I have cut down the fields above just to keep it easy to read. but the goal is to have all the line items and the purchase order header details on the one line.
public void WriteCSV<T>(IEnumerable<T> items, string path)
{
Type itemType = typeof(T);
var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.OrderBy(p => p.Name);
using (var writer = new StreamWriter(path))
{
writer.WriteLine(string.Join(fieldDelimiter, props.Select(p => p.Name)));
foreach (var item in items)
{
writer.WriteLine(string.Join(fieldDelimiter, props.Select(p => p.GetValue(item, null))));
}
}
}
I know I am missing how object work here so looking for some direction.
Much appreciated.
Instead of handling it in WriteCSV, you could pre-process the data to flatten (denormalize) it and then pass it to your existing WriteCSV:
var flatten = l.SelectMany(po => po.PurchaseOrderItems.Select(pi => new {
po.WHID,
po.Supplier_ID,
po.POID,
pi.SKU,
pi.Product_ID,
pi.QtyOrdered,
}));
WriteCSV(flatten);
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;
}