C# EF List from two classes - c#

I have two classes:
public partial class Alergy
{
public int ID { get; set; }
public Nullable<int> VaccinationAlergyID { get; set; }
public string PHN { get; set; }
public virtual VaccinationAlergy VaccinationAlergy { get; set; }
}
public partial class VaccinationAlergy
{
public VaccinationAlergy()
{
this.Alergies = new HashSet<Alergy>();
}
public int VaccinationAlergyID { get; set; }
public string VaccinationAlergyName { get; set; }
public virtual ICollection<Alergy> Alergies { get; set; }
}
I am using the following to get two values from these models using:
var vaccination = db.Alergies.Where(x => x.PHN == phn)
.Select(x => new { VaccinationAlergyID= x.VaccinationAlergyID,
VaccinationAlergyName= x.VaccinationAlergy.VaccinationAlergyName}).ToList();
I get only the first VaccinationAlergyName the rest are the id of VaccinationAlergyName.
Would appreciate your suggestions.

Try
var vaccination = db.Alergies.Where(x => x.PHN == phn).Include(x=> x.VaccinationAlergy).Select(x => new { VaccinationAlergyID= x.VaccinationAlergyID,VaccinationAlergyName=x.VaccinationAlergy.VaccinationAlergyName}).ToList();

Related

Why can't Entity Framework translate this linq query? "The LINQ expression could not be translated."

Why can't this query be translated? Just with one "First()" it works, with two it doesn't:
Exception:
The LINQ expression 'DbSet (whole query here) could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync*
await RecipesComparatorContext.ItemRecipesComparisonResults
.Where(compResult => (compResult.IdItemRecipeFromNavigation // From or two the same, both exist
.ItemRecipesTreeIdItemRecipeParentNavigations.First()
.ItemRecipesTreesRoots.First()
.IdItemRecipeRootNavigation
.MRPublishedVersions.First().PlantName == plantName)
)
)
.ExecuteUpdateAsync(result => result.SetProperty(r => r.InvalidState, true));
If it's solved with the ToListAsync(), where should I put it?
The Model is as follow:
public partial class ItemRecipesComparisonResult
{
public int IdItemRecipesComparisonResult { get; set; }
public int IdItemRecipeFrom { get; set; }
public int IdItemRecipeTo { get; set; }
public bool InvalidState { get; set; }
public virtual ItemRecipe IdItemRecipeFromNavigation { get; set; }
public virtual ItemRecipe IdItemRecipeToNavigation { get; set; }
}
public partial class ItemRecipe
{
public ItemRecipe()
{
ItemRecipesTreeIdItemRecipeChildNavigations = new HashSet<ItemRecipesTree>();
ItemRecipesTreeIdItemRecipeParentNavigations = new HashSet<ItemRecipesTree>();
MRPublishedVersions = new HashSet<MRPublishedVersion>();
}
public int IdItemRecipe { get; set; }
public virtual ICollection<ItemRecipesTree> ItemRecipesTreeIdItemRecipeChildNavigations { get; set; }
public virtual ICollection<ItemRecipesTree> ItemRecipesTreeIdItemRecipeParentNavigations { get; set; }
public virtual ICollection<ItemRecipesTreesRoot> ItemRecipesTreesRoots { get; set; }
public virtual ICollection<MRPublishedVersion> MRPublishedVersions { get; set; }
}
public partial class ItemRecipesTree
{
public ItemRecipesTree()
{
ItemRecipeInstances = new HashSet<ItemRecipeInstance>();
ItemRecipesTreesRoots = new HashSet<ItemRecipesTreesRoot>();
}
public int IdItemRecipeParent { get; set; }
public int IdItemRecipeChild { get; set; }
public virtual ItemRecipe IdItemRecipeChildNavigation { get; set; }
public virtual ItemRecipe IdItemRecipeParentNavigation { get; set; }
public virtual ICollection<ItemRecipesTreesRoot> ItemRecipesTreesRoots { get; set; }
}
public partial class ItemRecipesTreesRoot
{
public int IdItemRecipeTreeRoot { get; set; }
public int IdItemRecipeParent { get; set; }
public int IdItemRecipeChild { get; set; }
public int IdItemRecipeRoot { get; set; }
public virtual ItemRecipesTree IdItemRecipeNavigation { get; set; }
public virtual ItemRecipe IdItemRecipeRootNavigation { get; set; }
}
public partial class MRPublishedVersion
{
public int idVersion {get;set;}
public string PlantName {get;set;}
}
Rewrite query in the following way, it should be translatable:
var itemsToUpdate = RecipesComparatorContext.ItemRecipesComparisonResults
.Where(c => c.IdItemRecipeFromNavigation.ItemRecipesTreeIdItemRecipeParentNavigations
.SelectMany(p => p.ItemRecipesTreesRoots)
.SelectMany(r => r.IdItemRecipeRootNavigation.MRPublishedVersions)
.Any(v => v.PlantName == plantName)
);
await itemsToUpdate.ExecuteUpdateAsync(result => result.SetProperty(r => r.InvalidState, true));

Merge entities in Entity Framework 6

I have these entities which represent Menu and Labels SQL tables:
public class Menu
{
public int IdMenu { get; set; }
public int IdLabel { get; set; }
}
public class Label
{
public int IdLabel { get; set; }
public string Value { get; set; }
}
In a controller I have this method:
public IActionResult GetAll()
{
var menu = _service.GetAll();
var model = _mapper.Map<IList<MenuModel>>(menu);
return Ok(model);
}
but obviously, it gives me only IdMenu and IdLabel for each menu item.
What should I do to let it give me IdMenu and Value of Label?
Update n. 1:
Entities:
public class MenuPadre_EL
{
[Key]
public int IdMenuPadre { get; set; }
public int IdEtichetta { get; set; }
public string Icona { get; set; }
public MenuPadreUtente_EL menuPadreUtente { get; set; }
}
public class MenuPadreUtente_EL
{
public int IdMenuPadreUtente { get; set; }
public int IdUtente { get; set; }
public int IdMenuPadre { get; set; }
public MenuPadre_EL menuPadre { get; set; }
}
DataContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Etichetta>().HasKey(e => new { e.IdEtichetta, e.Lingua });
modelBuilder.Entity<MenuPadreUtente_EL>().HasKey(m => new { m.IdMenuPadre, m.IdUtente });
modelBuilder.Entity<MenuPadre_EL>()
.HasOne(mpu => mpu.menuPadreUtente)
.WithOne(mp => mp.menuPadre)
.HasForeignKey<MenuPadreUtente_EL>(mpu => mpu.IdMenuPadre);
}
Model:
public class MenuPadreUtente_ELModel
{
public int IdMenuPadreUtente { get; set; }
public int IdMenuPadre { get; set; }
public int IdUtente { get; set; }
public string Etichetta { get; set; }
public MenuPadre_EL menuPadre { get; set; }
}
API Output:
[
{
"idMenuPadreUtente": 1,
"idMenuPadre": 1,
"idUtente": 1,
"etichetta": null,
"menuPadre": null
}
]
why menuPadre is null?
You can do that as bellow:
[HttpGet]
public IActionResult GetAll()
{
var menu = menueList();
var lable = lableList();
var model = (from _menue in menu
join _lable in lable
on _menue.IdLabel equals _lable.IdLabel
select new
{
IdMenu = _menue.IdMenu,
Value = _lable.Value,
}).ToList();
return Ok(model);
}

From the tree structure get list

I have a class CategoryModel in c#, which is an element of a tree:
public class CategoryModel
{
public string Id { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public string ParentCategoryId { get; set; }
public ICollection<string> ChildCategoriesIds { get; set; } = new List<string>();
public ICollection<string> ProductsIds { get; set; } = new List<string>();
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
}
The ChildCategoriesIds contains Id class CategoryModel.
The ProductsIds contains Id class Product.
How proccesed data in new classes:
public class CategoryNew
{
public string Uid { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public bool? IsDeleted { get; set; }
public IEnumerable<UidName> ChildCategories { get; set; } = new List<UidName>();
public IEnumerable<UidName> Products { get; set; } = new List<UidName>();
}
public class UidName
{
public string Uid { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public bool? IsDeleted { get; set; }
}
You can specify own constructor for CategoryNew, which will take as an argument object of class CategoryModel, in which you will set all properties of CategoryNew based on values of properties of CategoryModel:
public CategoryNew(CategoryModel cm){
// set properties
}
Then your method would be:
public List<CategoryNew> ConverModelToNew(List<CategoryModel> lstCatModel){
List<CategoryNew> lstCatNew = new List<CategoryNew>();
foreach(var item in lstCatModel){
lstCatNew.Add(new CetagoryNew(item));
}
return lstCatNew;
}
Assuming you are trying to convert one set of object to another set of objects.
First of all, I believe categories shouldl inherit UidName so you will memory more efficiently by reducing duplicate objects.
public class CategoryNew: UidName
{
public IEnumerable<CategoryNew> ChildCategories { get; set; } = new List<CategoryNew>();
public IEnumerable<UidName> Products { get; set; } = new List<UidName>();
}
public class UidName
{
public string Uid { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public bool? IsDeleted { get; set; }
}
// first run to create products
var newProducts = products.Select(p => new UidName {
Uid = p.Id,
Name = p.Name,
NameEnd = p.NameEng
}).ToArray();
// second run to create categories with products
var newCategories = categories.Select(c => new CategoryNew {
Uid = c.Id,
Name = c.Name,
NameEng = c.NameEng,
IsDeleted = (bool?)null, //TODO
Products = newProducts.Where(p => c.ProductIds.Contains(p.Uid))
.ToList()
}).ToArray();
// last run find sub categories
foreach(var category in newCategories) {
var oldCategory = categories.First(c => c.Id == category.Uid);
category.ChildCategories = newCategories.Where(c => oldCategory.ChildCategoriesIds.Contains(c.Uid))
.ToArray();
}

Way to create composite objects from a single (flat) database query

I am getting product data from our ERP through SQL queries whereby the returned data is very flat- at the Size level. A product has 3 levels:
Style
Colours
Sizes
A style has many colours and a colour has many sizes.
I have created the following models:
public class Ap21Style
{
public int StyleIdx;
public string StyleCode;
public IList<Ap21Clr> Clrs { get; set; } = new List<Ap21Clr>();
}
public class Ap21Clr
{
public int ClrIdx { get; set; }
public string ColourCode { get; set; }
public string ColourName { get; set; }
public string ColourTypeCode { get; set; }
public string ColourTypeName { get; set; }
public IList<Ap21Sku> Skus { get; set; } = new List<Ap21Sku>();
}
public class Ap21Sku
{
public int SkuIdx { get; set; }
public string SizeCode { get; set; }
public int SizeSequence { get; set; }
public string Barcode { get; set; }
}
My ProductResult looks like this:
public int StyleIdx { get; set; }
public int ClrIdx { get; set; }
public int SkuIdx { get; set; }
public string StyleCode { get; set; }
public string ColourCode { get; set; }
public string ColourName { get; set; }
public string SizeCode { get; set; }
public int SizeSequence { get; set; }
public string ColourTypeCode { get; set; }
public string ColourTypeName { get; set; }
public string Barcode { get; set; }
public string WebData { get; set; }
What would be an effective way to loop over the results and create the Ap21Style models whereby they are a composite object with Ap21Clr's, then at the row level, the Colours have Ap21Sku's?
Assuming something like this
List<ProductResult> products = GetPropducts();
Composing the styles would involve grouping the data by the composite keys
List<Ap21Style> results = products
.GroupBy(p => new { p.StyleIdx, p.StyleCode })
.Select(g => new Ap21Style {
StyleIdx = g.Key.StyleIdx,
StyleCode = g.Key.StyleCode,
Clrs = g.GroupBy(s => new {
s.ClrIdx,
s.ColourCode,
s.ColourName,
s.ColourTypeCode,
s.ColourTypeName
}).Select(g1 => new Ap21Clr {
ClrIdx = g1.Key.ClrIdx,
ColourCode = g1.Key.ColourCode,
ColourName = g1.Key.ColourName,
ColourTypeCode = g1.Key.ColourTypeCode,
ColourTypeName = g1.Key.ColourTypeName,
Skus = g1.Select(s => new Ap21Sku {
Barcode = s.Barcode,
SizeCode = s.SizeCode,
SizeSequence = s.SizeSequence,
SkuIdx = s.SkuIdx
}).ToList()
}).ToList()
}).ToList();

How to access a model through List in MVC

I want to sort the ValidatingCarrier in ascending order so I thought of getting it into a List and sorting it using Orderby in my controller.
I have the following Model Classes:
public class sort
{
public OTAAirLowFareSearchRS OTA_AirLowFareSearchRS { get; set; }
}
public class OTAAirLowFareSearchRS
{
public int PricedItinCount { get; set; }
public int BrandedOneWayItinCount { get; set; }
public int SimpleOneWayItinCount { get; set; }
public int DepartedItinCount { get; set; }
public int SoldOutItinCount { get; set; }
public int AvailableItinCount { get; set; }
public string Version { get; set; }
public Success success { get; set; }
public Warnings Warnings { get; set; }
public PricedItineraries PricedItineraries { get; set; }
public TPAExtensions8 TPA_Extensions { get; set; }
}
public class PricedItinerary
{
public int SequenceNumber { get; set; }
public AirItinerary AirItinerary { get; set; }
public List<AirItineraryPricingInfo> AirItineraryPricingInfo { get; set; }
public TicketingInfo TicketingInfo { get; set; }
public TPAExtensions7 TPA_Extensions { get; set; }
}
public class AirItineraryPricingInfo
{
public string PricingSource { get; set; }
public string PricingSubSource { get; set; }
public ItinTotalFare ItinTotalFare { get; set; }
public PTCFareBreakdowns PTC_FareBreakdowns { get; set; }
public FareInfos2 FareInfos { get; set; }
public TPAExtensions6 TPA_Extensions { get; set; }
public string LastTicketDate { get; set; }
}
public class TPAExtensions6
{
public DivideInParty DivideInParty { get; set; }
public ValidatingCarrier ValidatingCarrier { get; set; }
}
The following is the way I am trying to access it in my controller. I cannot access beyond PriceItinerary cause the reset goes as a List.
sort searchResponse = JsonConvert.DeserializeObject<sort>(tar.ToString());
var sortingname = searchResponse.OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary;
List<PricedItinerary> lstname = new List<PricedItinerary>();
Any kind of help is appreciated....
You have create the object first
searchResponse.OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary obj = new searchResponse.OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary;
var x = obj.SequenceNumber;
Are you trying to access "AirItineraryPricingInfo" with the instance of "PricedItinerary"? If it is so, then this helps, otherwise please ignore.
public class PricedItinerary : AirItineraryPricingInfo
{
public int SequenceNumber { get; set; }
public AirItinerary AirItinerary { get; set; }
public List<AirItineraryPricingInfo> AirItineraryPricingInfo { get; set; }
public TicketingInfo TicketingInfo { get; set; }
public TPAExtensions7 TPA_Extensions { get; set; }
}
In controller if we create instance for "PricedItinerary", we can access inherited class.
You can do it with LINQ SelectMany makes a projection os IEnumerable into one IEnumerable.
With the given model and assuming that you need to get a list of ValidatingCarrier starting on PricedItinerary , let's go do it!
IEnumerable<ValidatingCarrier> IEValidatingCarrier = searchResponse.OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary
.SelectMany(p => p.AirItineraryPricingInfo.SelectMany(a => a.TPA_Extensions.ValidatingCarrier)); //This would give you an IEnumerable<ValidatingCarrier>
IEnumerable<ValidatingCarrier> LstValidatingCarrier = IEValidatingCarrier.OrderBy(o => o.OrderBySomething).ToList(); //And finally, your ordered list!
You can also do it all at once, something like this:
searchResponse.OTA_AirLowFareSearchRS.PricedItineraries.PricedItinerary
.SelectMany(p => p.AirItineraryPricingInfo.SelectMany(a => a.TPA_Extensions.ValidatingCarrier))
.OrderBy(o => o.OrderBySomething).ToList();
Hope it helps! Plase if I don't understand well your question, please let me know!

Categories

Resources