Populating viewmodel array - c#

What Am I doing wrong? In the code below (specifically on foreach), When I have more than one 'itens', just the last one will be on Itens array.
I am using a viewmodel array, as you can see below.
I would appreciate if you could give me a sample.
I created a repository class like this:
public async Task<PrintNFePedidoRoot> PedidoPrint(int idPedido)
{
using var db = new KeplerContext(_optionsBuilder);
var pedido = await db.Pedido.AsNoTracking()
.FirstOrDefaultAsync(m => m.IdPedido == idPedido);
var pedidoItens = await db.PedidoItens
.Where(i => i.IdPedido == idPedido)
.Include(p => p.IdProdutoNavigation)
.AsNoTracking().ToListAsync();
var pedidoPrint = new PrintNFePedidoRoot()
{
IdPedido = idPedido,
TotalValor = pedido.Val,
Desconto = 0,
Taxa = pedido.Tax,
TotalPagar = pedido.Tot,
};
var Itens = Array.Empty<PrintNFePedidoItens>();
foreach (PedidoItens i in pedidoItens)
{
if (i.IdProdutoMeia != null)
{
var produto = db.Produto
.AsNoTracking()
.First(p => p.IdProduto == i.IdProdutoMeia);
i.IdProdutoNavigation.Nome = i.IdProdutoNavigation.Nome + "/" + produto.Nome.Replace("Exp", "").Trim();
}
Itens = new[]
{
new PrintNFePedidoItens
{
IdProduto = i.IdProduto,
Nome = i.IdProdutoNavigation.Nome,
Valor = i.IdProdutoNavigation.Preco
}
};
}
pedidoPrint.Itens = Itens;
return pedidoPrint;
}
I created a viewModel class like these:
public class PrintNFePedidoRoot
{
[JsonProperty("id_pedido")]
public int IdPedido { get; set; }
[JsonProperty("total_valor")]
public int TotalValor { get; set; }
[JsonProperty("desconto")]
public int Desconto { get; set; }
[JsonProperty("taxa")]
public int Taxa { get; set; }
[JsonProperty("total_pagar")]
public int TotalPagar { get; set; }
[JsonProperty("pedido_itens")]
public PrintNFePedidoItens[] Itens { get; set; }
}
public class PrintNFePedidoItens
{
[JsonProperty("id_produto")]
public int IdProduto { get; set; }
[JsonProperty("nome")]
public string Nome { get; set; }
[JsonProperty("valor")]
public decimal Valor { get; set; }
}

Looks like you are assigning a new array with just one element to "Itens" instead to add values to the array.
Instead of this
Itens = new[]
{
new PrintNFePedidoItens
{
IdProduto = i.IdProduto,
Nome = i.IdProdutoNavigation.Nome,
Valor = i.IdProdutoNavigation.Preco
}
};
Try
Itens.Add(new PrintNFePedidoItens
{
IdProduto = i.IdProduto,
Nome = i.IdProdutoNavigation.Nome,
Valor = i.IdProdutoNavigation.Preco
});
Just be sure you are initializing correctly "Itens".

This way is working.
Instead of this:
var Itens = Array.Empty<PrintNFePedidoItens>();
I have changed to this:
var Itens = new List<PrintNFePedidoItens>();
Instead of this:
public class PrintNFePedidoRoot
{
...
[JsonProperty("pedido_itens")]
public PrintNFePedidoItens[] Itens { get; set; }
}
I have changed to this:
public class PrintNFePedidoRoot
{
...
[JsonProperty("pedido_itens")]
public List<PrintNFePedidoItens> Itens { get; set; }
}
So, I could used this:
Itens.Add(new PrintNFePedidoItens
{
IdProduto = i.IdProduto,
Nome = i.IdProdutoNavigation.Nome,
Valor = i.IdProdutoNavigation.Preco,
Qntd = i.Quantidade
});

Related

Automapper: same instance after mapping

I try Automapper and it is very nice but is it possible map two OuterDto source to OuterModel destination with same object InnerDeto like in code? How can I do that dest1.Inner and dest2.Inner after map has same instance? What I know, I think it is not possible. What do you think? Thanks for help me
public class OuterDto
{
public int Value { get; set; }
public InnerDto Inner { get; set; }
}
public class InnerDto
{
public int OtherValue { get; set; }
}
public class OuterModel
{
public int Value { get; set; }
public InnerModel Inner { get; set; }
}
public class InnerModel
{
public int OtherValue { get; set; }
}
public class test
{
public test()
{
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<InnerDto, InnerModel>().ReverseMap();
cfg.CreateMap<OuterDto, OuterModel>().ReverseMap();
});
config.AssertConfigurationIsValid();
InnerDto innerSource = new InnerDto { OtherValue = 15 };
var source1 = new OuterDto
{
Value = 1,
Inner = innerSource
};
var source2 = new OuterDto
{
Value = 2,
Inner = innerSource
};
var mapper = config.CreateMapper();
source1.Inner.OtherValue = 20;
var dest1 = mapper.Map<OuterDto, OuterModel>(source1);
var dest2 = mapper.Map<OuterDto, OuterModel>(source2);
dest1.Inner.OtherValue = 1000;
//Result:
//dest1.Inner.OtherValue = 1000
//dest2.Inner.OtherValue = 20
//Expected Result:
//dest1.Inner.OtherValue = 1000
//dest2.Inner.OtherValue = 1000
}
}
I'm not sure, but try to instanciate OuterModel before calling Map method
//...
var mapper = config.CreateMapper();
source1.Inner.OtherValue = 20;
var dest1 = new OuterModel();
mapper.Map(source1, dest1);
mapper.Map(source2, dest1);
dest1.Inner.OtherValue = 1000;
NOTE: I haven't tested my code, it's just to give food for thought

Filter data from 2 lists with diferent models C#

I have this models
public class RoutingAttributeModel
{
public int Bus_No { get; set; }
public int Attribute_No { get; set; }
public string Attribute_Name { get; set; }
public string Status { get; set; }
public string Notes { get; set; }
}
public class AgentRoutingAttributeModel
{
public int Agent_No { get; set; }
public int Bus_No { get; set; }
public int Attribute_No { get; set; }
public string Attribute_Name { get; set; }
public string Status { get; set; }
}
List<RoutingAttributeModel> lstComplete = new List<RoutingAttributeModel>();
List<AgentRoutingAttributeModel> lstAssigned = new List<AgentRoutingAttributeModel>();
Filled this with some data
Is it possible to filter with Linq? I want to save in a new list the diferent content between lstComplete and lstAssigned
I was trying to join both lists but got stuck there
var results1 = from cl in lstComplete
join al in lstAssigned
on cl.Attribute_No equals al.Attribute_No
select cl;
you can use linq
as my understanding, you try to find linked by attribute_No records and have a list of not matching properties?
lstComplete.Add(new RoutingAttributeModel(){
Attribute_Name = "aaa",
Attribute_No = 1,
Bus_No = 1,
Notes = "",
Status = "status"
});
lstAssigned.Add(new AgentRoutingAttributeModel()
{
Attribute_No = 1,
Agent_No = 10,
Bus_No = 1,
Attribute_Name = "bbb",
Status = "status2"
});
var lst = lstComplete
.Join(lstAssigned,
complete => complete.Attribute_No,
assigned => assigned.Attribute_No,
(complete, assigned) => new { lstComplete = complete, lstAssigned = assigned })
.Select(s => new { s.lstComplete, s.lstAssigned})
.Where(w=>
w.lstAssigned.Attribute_Name != w.lstComplete.Attribute_Name
|| w.lstAssigned.Bus_No != w.lstComplete.Bus_No
)
.ToList()
.Dump();
so result would be
You could try the following query
var filteredList = lstComplete
.Where(x => !lstAssigned.Any(y => y.Attribute_No == x.Attribute_No));

'Multiplicity constraint violated. The role 'Rayon_Produits_Source' of the relationship Rayon_Produits' has multiplicity 1 or 0..1.'

I would like to add many items to EF in order to put them to database, but I have this error (given in the title).
I searched on internet, but I only found some ideas based on the fact that an item can't be added twice, which seems logical. but I took care of giving different Ids (Id is the property which is the key in the associated table), but it does not work, I still have this error. By now, I have no idea of what could go wrong.
here are the datas I am trying to push to the database, after the different model classes:
the biggest container : Supermarche
[DataContract]
public class Supermarche
{
[Key]
[DataMember]
public int SupermarcheId { set; get; }
[DataMember]
public virtual ObservableCollection<Magasin> Magasins { set; get; }
}
it contains some "Magasin":
[DataContract]
public class Magasin : ElementSupermarche
{
[Key]
[DataMember]
public int MagasinId { set; get; }
[DataMember]
public string Nom { set; get; }
[DataMember]
public virtual ObservableCollection<Rayon> Rayons { set; get; }
}
which contains itself some "Rayon":
[DataContract]
public class Rayon : ElementSupermarche
{
[Key]
[DataMember]
public int RayonId { set; get; }
[DataMember]
public string Nom { set; get; }
[DataMember]
public virtual ObservableCollection<ProduitMagasin> Produits { set; get; }
}
which contains some "ProduitMagasin":
[DataContract]
public class ProduitMagasin : ElementSupermarche
{
[Key]
[DataMember]
public int ProduitMagasinId { set; get; }
[DataMember]
public string Nom { set; get; }
[DataMember]
public int Quantite { set; get; }
}
last, but not least, the filling part:
using (var ctx = new MarketContext("sqlserver"))
{
new MyDataInitializer().InitializeDatabase(ctx);
var produitMagasin1 = new ProduitMagasin() { Nom = "Pommes", Quantite = 10 };
var produitMagasin2 = new ProduitMagasin() { Nom = "Poires", Quantite = 5 };
var rayon1 = new Rayon() { RayonId = 1, Nom = "Fruits & légumes", Produits = new ObservableCollection<ProduitMagasin>() { produitMagasin1, produitMagasin2 } };
var produitMagasin5 = new ProduitMagasin() { Nom = "pizzas", Quantite = 4 };
var produitMagasin6 = new ProduitMagasin() { Nom = "quiches", Quantite = 8 };
var rayon3 = new Rayon() { RayonId = 2, Nom = "Surgelés", Produits = new ObservableCollection<ProduitMagasin>() { produitMagasin1, produitMagasin2 } };
var magasin1 = new Magasin() { Nom = "Auchan", Rayons = new ObservableCollection<Rayon>() { rayon1, rayon3 } };
ctx.SaveChanges();
var produitMagasin3 = new ProduitMagasin() { Nom = "melons", Quantite = 13 };
var produitMagasin4 = new ProduitMagasin() { Nom = "fraises", Quantite = 37 };
var rayon2 = new Rayon() { RayonId = 3, Nom = "Fruits & légumes", Produits = new ObservableCollection<ProduitMagasin>() { produitMagasin3, produitMagasin4 } };
var magasin2 = new Magasin() { Nom = "Carrefour", Rayons = new ObservableCollection<Rayon>() { rayon2 } };
var supermarche1 = new Supermarche() { Magasins = new ObservableCollection<Magasin> { magasin1, magasin2 } };
ctx.Supermarches.Add(supermarche1);
ctx.SaveChanges();
}
I don't think it is related, but here is the pull part which is in a WCF service and is executed right after the above code (in a different context, but there could be some time problem, maybe the computer reaches the pull part before having pushed the sample informations to the database:
using (var ctx2 = new MarketContext("sqlserver"))
{
ctx2.Configuration.ProxyCreationEnabled = false;
var sm = ctx2.Supermarches
.Include(s => s.Magasins.Select(mg => mg.Rayons.Select(r => r.Produits)))
.First();
return sm;
}
thank you
solved, the Rayon with RayonId=2 was containing the same Produits as the one with RayonId=1.

Find Unique count on field using LINQ

I am trying to determine the Distinct count for a particular field in a collection of objects.
private static RemittanceCenterBatchSummaryListModel SummarizeFields(RemittanceCenterSummaryListModel remittanceCenterSummaryListModel)
{
var result = remittanceCenterSummaryListModel.RemittanceBatchSummaryRecord.GroupBy(x => new{x.FileId, x.SourceFileName, x.BatchCode, x.BatchType})
.Select(x => new RemittanceCenterBatchSummarizedModel()
{
FileId = x.Key.FileId,
SourceFileName = x.Key.SourceFileName,
BatchCode = x.Key.BatchCode,
BatchType = x.Key.BatchType,
DetailRecordCountAdc = x.Count(y => y.BillingSystemCode == BillingSystemCode.Adc),
DetailRecordCountNotAdc = x.Count(y => y.BillingSystemCode == BillingSystemCode.Exd),
AmountAdc = x.Where(y => y.BillingSystemCode == BillingSystemCode.Adc).Sum(y => y.PaymentAmount),
AmountNotAdc = x.Where(y => y.BillingSystemCode == BillingSystemCode.Exd).Sum(y => y.PaymentAmount),
UniqueFileCount = x.Select(y => x.Key.FileId).Distinct().Count()
});
return CreateSummaryListModel(result);
}
Input entities:
public class RemittanceCenterSummaryListModel
{
public RemittanceCenterSummaryListModel()
{
this.RemittanceBatchSummaryRecord = new List<RemittanceBatchProcessingModel>();
}
public List<RemittanceBatchProcessingModel> RemittanceBatchSummaryRecord { get; private set; }
}
public class RemittanceCenterBatchSummarizedModel
{
public string FileId { get; set; }
public string SourceFileName { get; set; }
public string BatchCode { get; set; }
public string BatchType { get; set; }
public int DetailRecordCountAdc { get; set; }
public int DetailRecordCountNotAdc { get; set; }
public int DetailRecordCountTotal { get; set; }
public decimal AmountAdc { get; set; }
public decimal AmountNotAdc { get; set; }
public decimal AmountTotal { get; set; }
public BillingSystemCode BillingSystemCode { get; set; }
public int UniqueFileCount { get; set; }
}
private static RemittanceCenterBatchSummaryListModel CreateSummaryListModel(IEnumerable<RemittanceCenterBatchSummarizedModel> summaryModels)
{
var summaryModelList = new RemittanceCenterBatchSummaryListModel();
foreach (var summaryRec in summaryModels)
{
var summaryModel = new RemittanceCenterBatchSummarizedModel
{
FileId = summaryRec.FileId,
SourceFileName = summaryRec.SourceFileName,
BatchCode = summaryRec.BatchCode,
BatchType = summaryRec.BatchType,
DetailRecordCountAdc = summaryRec.DetailRecordCountAdc,
DetailRecordCountNotAdc = summaryRec.DetailRecordCountNotAdc,
AmountAdc = summaryRec.AmountAdc,
AmountNotAdc = summaryRec.AmountNotAdc,
UniqueFileCount = summaryRec.UniqueFileCount
};
summaryModelList.RemittanceBatchSummary.Add(summaryModel);
}
return summaryModelList;
}
Example input records:
Record1:
FileId: '123'
SourceFileName: 'test.file.txt'
BatchCode: 'aaa'
BatchType: 'scanned'
PaymentAmount: '50.00'
BillingSystemCode: 'Adc'
Record1:
FileId: '1234'
SourceFileName: 'test.file2.txt'
BatchCode: 'aab'
BatchType: 'scanned'
PaymentAmount: '52.00'
BillingSystemCode: 'Adc'
ActualOuput for UniqueFileCount Field:
UniqueFileCount = 1
ExpectedOutput results for UniqueFileCount Field:
UniqueFileCount = 2
What am I doing wrong?
It sounds like you want the distinct count of FileId for the entire collection and not just for each group, which will always be 1 since FileId is one of the fields you group on. If that is the case then you can just calculate that count first
int distinctFileIds = remittanceCenterSummaryListModel.RemittanceBatchSummaryRecor‌​d
.Select(x => x.FileId)
.Distinct()
.Count();
Then use that in your Linq query
UniqueFileCount = distinctFileIds

How to push to do a emdeded document in mongodb c# driver

i have a problem how to push a document into a another document to create a embeded document in c#.
my models look like :
public class ModelKnjiga
{
public ModelKnjiga() { }
[BsonId(IdGenerator = typeof(CombGuidGenerator))] // pojavljuje se greška kod BSON tipa podataka kod ID-a,preuzoteo s dokumentacije drivera 1.5
public Guid Id { get; set; }
[BsonElement("naziv")]
public string naziv { get; set; }
[BsonElement("autor")]
public string autor { get; set; }
[BsonElement("godina_izdanja")]
public string godina_izdanja { get; set; }
[BsonElement("izdavac")]
public string izdavac { get; set; }
[BsonElement("ocjena")]
public String ocjena { get; set; }
[BsonElement("čitam")]
public Boolean čitam { get; set; }
[BsonElement("završio")]
public Boolean završio { get; set; }
}
another model looks like :
public ModelKorisici () {
KnjigaLista = new List<ModelKnjiga>();
}
[BsonId] // pojavljuje se greška kod BSON tipa podataka kod ID-a,preuzoteo s dokumentacije drivera 1.5 CombGuidGenerator
public Guid Identifikator { get; set; }
[BsonElement("ime")]
public string ime { get; set; }
[BsonElement("prezime")]
public string prezime { get; set; }
[BsonElement("lozinka")]
public string lozinka { get; set; }
[BsonElement("email")]
public string email { get; set; }
[BsonElement("kor_ime")]
public string kor_ime { get; set; }
[BsonElement("uloga")]
public string uloga { get; set; }
public List<ModelKnjiga> KnjigaLista { get; set; }
}
and now i am tring to push a modelKnjiga into a modelKorisici
I am trying with this method...
public void dodajKnjiguKorisniku(ModelKnjiga knjiga, Guid id)
{
MongoCollection<ModelKorisici> korisniciKolekcija = GetTasksCollectionKlijenti();
try
{
var pronadiKorisnika = Query<ModelKorisici>.EQ(e => e.Identifikator, id);
var PushPodataka = Update<ModelKorisici>.Push(e => e.KnjigaLista, knjiga);
korisniciKolekcija.Update(pronadiKorisnika, PushPodataka);
}
catch (MongoCommandException ex)
{
string msg = ex.Message;
}
}
In robomongo, the object KnjigaLista is always Null...
Can somebody help?
I think Update is legacy.
(in your models you don't have to use strings only. Eg.: godina_izdanja could be DateTime(), and ocjena some numeric format...)
I made an (async) example with your models, hope it helps:
class Program
{
static void Main(string[] args)
{
MainAsync(args).GetAwaiter().GetResult();
Console.WriteLine("");
Console.WriteLine("press enter");
Console.ReadKey();
}
static async Task MainAsync(string[] args)
{
ModelKnjiga knga = new ModelKnjiga()
{
autor = "Author",
godina_izdanja = "2015",
izdavac = "izdavac",
naziv = "naziv",
ocjena = "20",
završio = true,
čitam = true
};
ModelKnjiga knga2 = new ModelKnjiga()
{
autor = "Author2",
godina_izdanja = "2016",
izdavac = "izdavac2",
naziv = "naziv2",
ocjena = "202",
završio = false,
čitam = false
};
ModelKnjiga knga3 = new ModelKnjiga()
{
autor = "Author3",
godina_izdanja = "2017",
izdavac = "izdavac3",
naziv = "naziv3",
ocjena = "203",
završio = false,
čitam = true
};
ModelKorisici mcor = new ModelKorisici()
{
email = "no#where.com",
ime = "ime",
KnjigaLista = new List<ModelKnjiga>() { knga, knga2 },
kor_ime = "kor_ime",
uloga = "uloga",
lozinka = "lozinka",
prezime = "prezime"
};
var client = new MongoClient();
var db = client.GetDatabase("KnjigaDB");
var korisici = db.GetCollection<ModelKorisici>("Korisici");
//After first run comment this line out
await korisici.InsertOneAsync(mcor);
//After first run UNcomment these lines
//var filter = Builders<ModelKorisici>.Filter.Eq("email", "no#where.com");
//var update = Builders<ModelKorisici>.Update.Push("KnjigaLista", knga3);
//await korisici.UpdateOneAsync(filter, update);
}
}
if you don't like async, change the last line with this:
korisici.UpdateOne(filter, update);

Categories