Using linq or plain c# to populate a given object structure - c#

I am trying to populate the AllTerms object that will contain LegalFundClassCommercialViewModel and LegalFundClassSideLetterViewModel objects.
Basically the LEGAL_FUND_CLASS table has parent and child records and are related by column LegalParentClassId. One parent has one child. So I need to loop through legalfundClasses object and populate
IEnumerable<LegalFundClassWrapper> AllTerms . The LegalFundClassDetailsViewModel represents the records in the LEGAL_FUND_CLASS table. So legalfundClasses variable contains records from this legal_fund_class table. There are several records. Some records wont have child record. I need to populate in a way where the parent record gets added to LegalFundClassCommercialViewModel and its child record gets added to
LegalFundClassSideLetterViewModel. The wrapper would contain a collection of Parent and child records where some child records wont exist and hence the LegalFundClassSideLetterViewModel property would be null.
Can somebody give me an idea on how to go about it ?
C#
public class LegalFundClassViewModel
{
public IEnumerable<LegalFundClassWrapper> AllTerms;
public class LegalFundClassWrapper
{
public LegalFundClassDetailsViewModel LegalFundClassCommercialViewModel { get; set; }
public LegalFundClassDetailsViewModel LegalFundClassSideLetterViewModel { get; set; }
}
}
public class LegalFundClassDetailsViewModel
{
public string Description { get; set; }
public string AuditSummary { get; set; }
public string FeesReviewSummary { get; set; }
public string TermsReviewSummary { get; set; }
public int Id { get; set; }
public int FundId { get; set; }
public int FundClassType { get; set; }
public int? CurrencyId { get; set; }
public string PrimaryCurrencyName { get; set; }
public string OtherCurrencyName { get; set; }
public int? ManagerStrategyId { get; set; }
public string ManagerStrategyName { get; set; }
public int? SubVotingId { get; set; }
public string SubVotingName { get; set; }
public int? SubHotIssueId { get; set; }
public string SubHotIssueName { get; set; }
public int? RedsFrqncyId { get; set; }
public string RedsFrqncyName { get; set; }
public int? RedsNoticeDays { get; set; }
public int? NoticeTypeOfDaysId { get; set; }
public string NoticeTypeOfDaysName { get; set; }
public int? LegalParentClassId { get; set; }
}
var managerStrategyFundIds = GetService<MANAGERSTRATEGY>().WhereWithIncludes<MANAGERSTRATEGY>(x => x.ID == managerStratedyId, x => x.FUNDs).SelectMany(x => x.FUNDs).Select(x => x.ID).ToList();
var legalfundClasses = GetService<LEGAL_FUND_CLASS>().Where(x => managerStrategyFundIds.Contains(x.FUND_ID));
What I was trying creates a list of all the records in one. How do I loop through and populate the AllTerms
var allFunds = legalfundClasses.Select(fc => new LegalFundClassDetailsViewModel
{
Description = fc.DESCRIPTION,
Id = fc.ID,
FundId = fc.FUND_ID,
FundClassType = fc.CLASS_TYPE,
AuditSummary = getAuditSummary(managerStratedyId, fc.ID),
FeesReviewSummary = getFeesReviewSummary(fc),
TermsReviewSummary = getTermsReviewSummary(fc),
CurrencyId = fc.CURRENCY_ID,
});
public class LegalFundClassViewModel
{
public IEnumerable<LegalFundClassWrapper> AllTerms;
public class LegalFundClassWrapper
{
public LegalFundClassDetailsViewModel
LegalFundClassCommercialViewModel { get; set; }
public LegalFundClassDetailsViewModel
LegalFundClassSideLetterViewModel { get; set; }
}
As you can see in the image below, there are two records. The record that has value in legal_parent_class id field is the child to the record on top of it. If you notice the id of the top record matches the bottom record's legal_parent_class_id.
What is the best way to identify the child and store records in respective properties accordingly

You need left outer join. In your case
var allFunds = new[]
{
new LegalFundClassDetailsViewModel
{
Id = 101,
Description = "Parent with child"
},
new LegalFundClassDetailsViewModel
{
Id = 102,
Description = "Parent without child"
},
new LegalFundClassDetailsViewModel
{
Id = 103,
Description = "I'm child",
LegalParentClassId = 101
}
};
var allTerms = (from fund in allFunds
where fund.LegalParentClassId == null //only parents
join child in allFunds on fund.Id equals child.LegalParentClassId into gj
from child2 in gj.DefaultIfEmpty()
select new LegalFundClassViewModel.LegalFundClassWrapper { LegalFundClassCommercialViewModel = fund, LegalFundClassSideLetterViewModel = child2 })
.ToArray();

Related

How to get all the relation with filter

I have This object
public class ParentGroup
{
public int Id { get; set; }
public ParentGroup Parent { get; set; }
public int? ParentId { get; set; }
public ICollection<ParentGroup> Children { get; set; }
public ParentGroupType ParentGroupType { get; set; }
public int? ParentGroupTypeId { get; set; }
public bool Active { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
I'm trying to get all the parent with all the children but there is a something that happened with me and I can't understand if I put the where filter in the query I can't get all the data related to the children I got only the first level
If I removed it I get all the date with all the levels and I don't want to make the query to the DB, not my memory
This my code
public async Task<List<ParentGroup>> GetOrganizationStructureTree()
{
// var query = _context.ParentGroups.Where(x => x.ParentId == null);
List<ParentGroup> ParentGroups = await _context.ParentGroups.Include(par => par.Children).Include(par => par.Parent).Include(pr => pr.ParentGroupType).ToListAsync();
return ParentGroups;
}

Add data to List of object

I am relatively new to .net. I have a situation where I have a class
public class Product
{
public string sku { get; set; }
public string ean { get; set; }
public string price { get; set; }
public string description { get; set; }
public string long_description { get; set; }
public string img_url { get; set; }
public Size size { get; set; }
public Style style { get; set; }
public Brand brand { get; set; }
public Color color { get; set; }
public Category category { get; set; }
public List<Attributes> attributes { get; set; }
}
public class Attributes
{
public List<Attribute> attribute { get; set; }
}
public class Attribute
{
public string name { get; set; }
public string value { get; set; }
}
now my question is I want to add values to List.But facing some problem in adding values to attribute.
I have tried the following,
List<Product> products = new List<Product>();
products = (from inventory in inventoryDetails.AsEnumerable()
select new Product
{
ean = !string.IsNullOrEmpty(inventory.ean) ? inventory.ean : null,
sku = !string.IsNullOrEmpty(inventory.sku) ? inventory.sku : null,
}).ToList();
How to add attribute values? Can anyone please help?
You have multiple ways to write this
without lambda expression
List<Product> products = (from inventory in inventoryDetails.AsEnumerable()
select new Product
{
ean = !string.IsNullOrEmpty(inventory.ean) ? inventory.ean : null,
sku = !string.IsNullOrEmpty(inventory.sku) ? inventory.sku : null,
attributes = inventory.attributes.Select(x => new Attributes
{
//Set properties
}).ToList()
}).ToList();
With Lambda Expression
List<Product> products = inventoryDetails.Select(inventory => new Product
{
ean = !string.IsNullOrEmpty(inventory.ean) ? inventory.ean : null,
sku = !string.IsNullOrEmpty(inventory.sku) ? inventory.sku : null,
attributes = inventory.attributes
// if you want to set properties uncomment below lines and comment above line
//attributes = inventory.attributes.Select(y => new Attributes
//{
////Set properties
//}).ToList()
}).ToList();
You didn't share about inventoryDetails but you could apply select for also attributes;
products = (from inventory in inventoryDetails.AsEnumerable()
select new Product
{
ean = !string.IsNullOrEmpty(inventory.ean) ? inventory.ean : null,
sku = !string.IsNullOrEmpty(inventory.sku) ? inventory.sku : null,
attributes = inventory.attributes.Select(x => new Attributes
{
//Set properties
})
}).ToList();
When a model class cantains a List or collection fields we must intiate them at class constructor like this
public class Product
{
public Product()
{
this.attributes = new List<Attributes>();
}
public string sku { get; set; }
public string ean { get; set; }
public string price { get; set; }
public string description { get; set; }
public string long_description { get; set; }
public string img_url { get; set; }
public Size size { get; set; }
public Style style { get; set; }
public Brand brand { get; set; }
public Color color { get; set; }
public Category category { get; set; }
public List<Attributes> attributes { get; set; }
}
If any case Attribues model is mapped to database then use Icollection instead of List
public Product()
{
this.attributes = new ICollection<Attributes>();
}

Duplicating C# ASP.net object recursively with child & parent nodes

I am trying to create an endpoint to take the ID of the "manualMaster" and duplicate it & all of its children which reside inside of a tree like structure, each node has a parent which are all tied to the main parent being the ManualMaster.
Below are the models used
public class ManualStep
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Directions { get; set; }
public int MasterId { get; set; }
public ManualMaster Master { get; set; }
public int Index { get; set; } // This property governs where inside of the manual master this step belongs
public virtual ICollection<Image> Images { get; set; } // Virtual because I think I'd always like to have the attached image objects.
public DateTime Created { get; set; }
public DateTime LastModified { get; set; }
//Begin tree storage scheme
public int? ParentId { get; set; }
public ManualStep Parent { get; set; }
public ICollection<ManualStep> Nodes { get; set; }
}
public class ManualMaster
{
public int Id { get; set; }
public string Name { get; set; }
public int BrandId { get; set; }
public Brand Brand { get; set; }
public string Comment { get; set; }
public ICollection<ManualStep> Steps { get; set; }
public DateTime Created { get; set; }
public DateTime LastModified { get; set; }
}
And then the endpoint which takes the ID and attempts to duplicate.
// GET/DUPLICATE: api/Manual/5
[Route("{id}")]
[HttpGet]
[ResponseType(typeof(ManualMaster))]
public async Task<IHttpActionResult> DuplicateManualMaster(int id)
{
ManualMaster manualMaster = await db.ManualMasters
.Include(i => i.Steps)
.FirstOrDefaultAsync(i => i.Id == id);
//
if (manualMaster == null)
{
return NotFound();
}
var dup = new ManualMaster
{
Brand = db.Brands.FirstOrDefault(i => i.Id == manualMaster.BrandId),
BrandId = manualMaster.BrandId,
//manualMaster.Id,
Name = manualMaster.Name,
Comment = manualMaster.Comment
};
foreach (var step in manualMaster.Steps)
{
var newStep = step;
newStep.Parent.Id = dup.Id;
db.ManualSteps.Add(newStep);
await db.SaveChangesAsync();
}
db.ManualMasters.Add(dup);
await db.SaveChangesAsync();
return Ok(dup);
}
My problem is that currently when duplicating, I am setting the id of every node to the main parent ID and not to their respective ID's which create the tree structure.
newStep.Parent.Id = dup.Id;
So instead of copying the entire tree all of my nodes have the same ID... Instead I need to copy the tree structure how it currently is...

Fill the IList Collection using Entity Framework

Below is the Entity class
public partial class TestPlanViewModel
{
public TestPlanViewModel()
{
this.TestPlanTestPoints = new List<TestPlanTestPoint>();
}
public int TestPlanId { get; set; }
public string TestPlanName { get; set; }
public virtual IList<TestPlanTestPoint> TestPlanTestPoints { get; set; }
}
public class TestPlanTestPoint
{
public int OrganizationId { get; set; }
public int TestPlanId { get; set; }
public string TestPlanName { get; set; }
public int TestPlanVersion { get; set; }
public int TestPointId { get; set; }
public string TestPointName { get; set; }
}
I need to write a query where I need to get the collections from the dbContext like,
var query = (from tpm in TestPlanMaster
join tptp in TestPlanTestPoint on tpm.TestPlanId equals tptp.TestPlanId
join tmm in TestMethodMaster on tptp.TestMethodId equals tmm.TestMethodId
join tpma in TestPointMaster on tptp.TestPointId equals tpma.TestPointId
select new
{
//Plan Details
tpm.TestPlanId,
tpm.TestPlanName,
}).ToList().Select(x => new Entities.CustomEntities.TestPlanViewModel ====> Custom Entity
{
TestPlanId = x.TestPlanId,
TestPlanName = x.TestPlanName,
TestPlanTestPoints = ?????? ==> how to fill this collection
});
As shown above the TestPlanTestPoints is the IList collection object. I need to populate the data with the values from TestPlanTestPoint table.
Any suggestions?
Model
TestPlan
public partial class TestPlanMaster
{
[DataMember]
public int TestPlanId { get; set; }
[DataMember]
public short TestPlanVersion { get; set; }
[DataMember]
public int OrganizationId { get; set; }
[DataMember]
public short TestPlanTypeId { get; set; }
[DataMember]
public string TestPlanName { get; set; }
}
TestPlanTestPointMapping Model
public partial class TestPlanTestPointMapping
{
[DataMember]
public int OrganizationId { get; set; }
[DataMember]
public int TestPlanId { get; set; }
[DataMember]
public short TestPlanVersion { get; set; }
[DataMember]
public int TestPointId { get; set; }
}
You are thinking too much sql, think more linq. You want to select "tpm" items, so just write a select of those and select the new TestPlanViewModel and fill its properties and navigational properties.
I'm assuming you have a TestPlanTestPoints navigational property in your TestPlanMaster.
var q = (from tpm in TestPlanMaster
select new TestPlanViewModel
{
TestPlanId = tpm.TestPlanId,
TestPlanName = tpm.TestPlanName,
TestPlanPoints = TestPlanTestPoint.Where(pr => tpm.TestPlanId == pr.TestPlanId).Select(tptp => new TestPlanTestPoint()
{
// Fill properties here
}
}).ToList();

How to use Multi-Mapper to create multiple one to many object hierarchy

I have my 2 models like below
public class FItem
{
public FItem() { }
public int RecordId { get; set; }
public int MarketId { get; set; }
public string ItemName { get; set; }
public string ItemFamily { get; set; }
public string HoverFamily { get; set; }
public string ItemDesc { get; set; }
public IEnumerable<FSubsystem> FSubsystems { get; set; }
}
public class FSubsystem
{
public FSubsystem() { }
public int FSubsystemId { get; set; }
public int RecordId { get; set; } //Foreign key
public int supplierId { get; set; }
public int SubSystemTypeId { get; set; }
public double Percentage { get; set; }
public double? Value { get; set; }
}
public class FReferences
{
public FReferences() { }
public int RecordID { get; set; } //Foreign key
public int SourceID { get; set; }
public DateTime SourceDate { get; set; }
public string Reference { get; set; }
public int? ReferenceID { get; set; }
}
and I use dapper to fetch the data and put into objects . code is as belolw
using (var multi = mapperConnection.QueryMultiple("USP_FetchMarketRecords", parameters, (SqlTransaction)null, 1000000, CommandType.StoredProcedure))
{
IEnumerable<MarketRecord.FItem> FItem = multi.Read<MarketRecord.FItem>().ToList();
IEnumerable<MarketRecord.FSubsystem> FSubsystem = multi.Read<MarketRecord.FSubsystem>().ToList();
}
Now I want to get the subsystems for each record id and put them in FSubsystems property of Fitem . How can I do this ?
Here I am showing only one one to many relationship to FItem thats Fsubsystem . But I have many one to many tables to Fitem like FReferenc ,FUnit etc . For all foreign key is RecordId itelf.
Can this be done through linq query ? or should I use some diff technique ?
Dapper doesn't include anything built in to reconstruct parent/child relationships from different sets.
You can probably generalize the scenario something like:
static void ApplyParentChild<TParent, TChild, TId>(
this IEnumerable<TParent> parents, IEnumerable<TChild> children,
Func<TParent, TId> id, Func<TChild, TId> parentId,
Action<TParent, TChild> action)
{
var lookup = parents.ToDictionary(id);
foreach (var child in children)
{
TParent parent;
if (lookup.TryGetValue(parentId(child), out parent))
action(parent, child);
}
}
so if we had:
List<Parent> parents = new List<Parent> {
new Parent { Id = 1 },
new Parent { Id = 2 }
};
List<Child> children = new List<Child> {
new Child { Id = 3, ParentId = 1},
new Child { Id = 4, ParentId = 2},
new Child { Id = 5, ParentId = 1}
};
You could use:
parents.ApplyParentChild(children, p => p.Id, c => c.ParentId,
(p,c) => p.Children.Add(c));

Categories