how to merge / join two different list into 1 - c#

I am working on an application for Windows Phone platform. Run into a question.
I'd 2 different List, 1 is direct read from xml file, and the other by some calculation. And I want to merge this two lists into 1, so I can display it out.
List 1:
public class studentClass1
{
public string studentID { get; set; }
public string studentFirstName { get; set; }
public string studentLastName { get; set; }
}
List 2:
public class studentClass2
{
public string studentID { get; set; }
public string studentGradePoint { get; set; }
}
First of all, I had readout the studentClass1 via
var studentList= from query in studentIndex.Descendants("student")
select new driversClass
StudentList1 = studentList.ToList();
Secondly, I process the student Grade Point calculation on the function and output to the 2nd list :
studentClass2 SG = new studentClass2
{
studentID = thestudentID ,
studentGradePoint = thestudentGradePoint .ToString()
};
StudentList2.Add(SG);
studentListAll = StudentList1 + StudentList2
now, I want to join this two list together so that I can output to screen by calling
studentResultListBox.Itemsource = StudentListAll;
any suggestion the code how would look like?
Thanks.

Assuming you just want to combine the appropriate info from both lists (it is not totally clear from your question) - introduce a third class studentClass3 that holds all the properties you want and use a join to match instances with a matching studentID:
var studentList3 = (from s1 in studentList1
join s2 in studentList2 on s1.studentID equals s2.studentID
select new studentClass3()
{
studentFirstName = s1.studentFirstName,
studentID = s1.studentID,
studentGradePoint = s2.studentGradePoint,
studentLastName = s1.studentLastName
}).ToList();
In general this problem should be rather solved when you read in the XML than trying to combine the lists later on - having three different classes for students might be confusing. Also take a look at the recommended naming conventions, they are a little off.

Use interface, e.g.
interface IStudent
{
string studentID { get; }
// other common properties below
}
public class StudentClass1 : IStudent
{
public string studentID { get; set; }
public string studentFirstName { get; set; }
public string studentLastName { get; set; }
}
public class StudentClass2 : IStudent
{
public string studentID { get; set; }
public string studentGradePoint { get; set; }
}
and then
studentResultListBox.Itemsource = list1.Cast<IStudent>()
.Concat(list2.Cast<IStudent>())
.ToList();
Or, if the inheritance is not the case, just cast everything to System.Object (+ override object.ToString)
studentResultListBox.Itemsource = list1.Cast<object>()
.Concat(list2.Cast<object>())
.ToList();

Related

EF Core recursive folder structure serialized incorrectly

I'm trying to utilize EF Core to execute a Raw Sql statement and "serialize" it back to a recursive object structure.
My data looks like this
Folders -
Requests -
//Folder.cs
[Table("PsRequestFolder")]
public class PsRequestFolder : IWorkSpaceNode
{
[Key]
public int FolderId { get; set; }
public string FolderName = "";
public PsWorkSpace? FolderWorkSpace { get; set; }
public PsRequestFolder? ParentFolder { get; set; }
public List<PsHttpRequest> Requests { get; set; } = new List<PsHttpRequest>();
public List<PsRequestFolder> Folders { get; set; } = new List<PsRequestFolder>();
...
// Request.cs
[Table("PsHttpRequest")]
public class PsHttpRequest : IWorkSpaceNode
{
[Key]
public int RequestId { get; set; }
public string Url = "";
public string RequestName = "";
public PsWorkSpace RequestWorkSpace{ get; set; }
public int PsRequestFolderFolderId { get; set; }
public PsRequestFolder ContainingFolder { get; set; }
...
I'm executing this sql statement by calling FromSqlRaw
ws.RequestFolders = await context.RequestFolders.FromSqlRaw(
#"
WITH cte_ws AS (
SELECT
FolderId,
FolderName,
ParentFolderFolderId,
FolderWorkSpaceWorkSpaceId,
p1.*
FROM PsRequestFolder
LEFT JOIN PsHttpRequest AS p1 ON PsRequestFolder.FolderId = p1.PsRequestFolderFolderId
WHERE ParentFolderFolderId IS NULL
UNION ALL
SELECT
e.FolderId,
e.FolderName,
e.ParentFolderFolderId,
e.FolderWorkSpaceWorkSpaceId,
p1.*
FROM PsRequestFolder as e
LEFT JOIN PsHttpRequest AS p1 ON e.FolderId = p1.PsRequestFolderFolderId
INNER JOIN cte_ws o
on o.FolderId= e.ParentFolderFolderId
)
SELECT * FROM cte_ws;
"
).ToListAsync();
I would expect to get back something that looks like
One
RequestOne
RequestTwo
Two
Six
Eight
Nine
RequestThree
Seven
Three
Four
Five
Instead I get something like this back
Not sure why some of the things that should be nested underneath others aren't being nested as well as why the requests under folder Nine don't come through at all, as well folder Nine and some others being written twice to the list
The raw sql output just running it against the db is -
Any assistance is greatly appreciated!

writing LINQ query to pivot the result

I have developed a LINQ query. Now my requirement is to create pivot query from it. I am new to LINQ, I do not know how to proceed further. Please see the attached the attached result image.
public JsonResult SchoolNikashaRpt()
{
try
{
var temp = (from n in db.Nikashas
join s in db.Schools on n.SchoolId equals s.SchoolId
join k in db.Programs on n.ProgramId equals k.ProgramId
orderby n.SchoolId
select new RptSchoolsNikashaViewModel
{
SCHOOL_NAME = s.SCHOOL_NAME
,PROGRAM_NAME = k.PROGRAM_NAME
,MAPPED_AMOUNT = n.MAPPED_AMOUNT
}).ToList();
return Json(temp, JsonRequestBehavior.AllowGet);
}
catch (Exception)
{
throw;
}
}
Involved model classes are as follows::
public class NikashaModels
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int NIKASHAId { get; set; }
[Required]
public decimal MAPPED_AMOUNT { get; set; }
[ForeignKey("ProgramId")]
public ProgramModels Program { get; set; }
public int ProgramId { get; set; }
[ForeignKey("SchoolId")]
public SchoolModels School { get; set; }
public int SchoolId { get; set; }
}
public class SchoolModels
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int SchoolId { get; set; }
public string SCHOOL_NAME { get; set; }
}
public class ProgramModels
{
[Key]
public int ProgramId { get; set; }
public string PROGRAM_NAME { get; set; }
}
So you have Nikashas, Schools and Programs. There is a one-to-many relation: Every Nikasha has exactly one School, and exactly one Program, namely the School and Program that the foreign key refers to. In the other direction: Every School has zero or more Nikashas, every Program has zero or more Nikashas.
You want for every Nikasha, some properties, and some information of its School and its Program. For this you can use one of the overloads of Enumerable.Join, if more than two tables are involved it is easier to do this using Enumerab.Select
You didn't mention it, but because I see the word db, it seems to me that you are fetching the data from a DbContext, so your Enumerables are IQueryable<...>. This doesn't influence the answer very much:
IQueryable<Nikasha> nikashas = db.Nikashas
// only if you don't want all Nikashas:
.Where(nikasha => ...);
IQueryable<School> schools = ...
IQueryable<Program> programs = ...
var result = nikashas.Select(nikasha => new RptSchoolsNikashaViewModel
{
// Get the name of the one and only School of this nikasha
SchoolName = schools
// Keep only the School that the foreign key refers to:
.Where(school => school.Id == nikasha.SchoolId)
// Select the name of the School
.Select(school => school.SchoolName)
// and take the first element
.FirstOrDefault(),
// Do something similar with the program name:
ProgramName = programs.Where(program => program.Id == nikasha.ProgramId)
.Select(program => program.ProgramName)
.FirstOrDefault(),
MappedAmount = nikasha.MappedAmount,
});
In words: from every Nikasha, make one new RptSchoolsNikashaViewModel. For this RptSchoolsNikashaViewModel use the MappedAmount of the Nikasha. To get the SchoolName, take all Schools that have a primary key value equal to the foreign key in the Nikasha. From the remaining schools (probably only one), take the name of the School. Finally take the first item from the remaining school names. Do something similar for ProgramNames.

Determine if all items in ICollection<T> are not contained in List<T> using Linq query

so this is the setup:
Rule Model
public class Rule
{
public int RuleId { get; set; }
public BillOfMaterial BillOfMaterial { get; set; }
public ICollection<Option> MustNotContainAllOptions { get; set; }
}
Option Model
public class Option
{
public int OptionId { get; set; }
public string OptionCode { get; set; }
public ICollection<Rule> MustNotContainAllRules { get; set; }
}
I am trying to query a rule for its bill of materials from a given base and list of options. The only condition at this point is that the rule can't contain any of a given list of options.
Example Input
Input Options: PA,PB
Example Rule
Rule: MustNotContainOptions = PA, Bill Of Material = BOM1
In this case the query should return nothing since the input has option PA
What I have tried
OptionList = The input list of options
var MustNotContainAnyQuery = (from rule in db.Rules
where rule.MustNotContainAllOptions.Any(option => !OptionList.Contains(option.OptionCode))
select rule.BillOfMaterial.BomNumber);
and
var MustNotContainAnyQuery = (from rule in db.Rules
where rule.MustNotContainAllOptions.All(option => !OptionList.Contains(option.OptionCode))
select rule.BillOfMaterial.BomNumber);
I can't seem to lock this down. If someone could explain what I am doing wrong that would be a great help.
Thank you
If OptionList is a list of Options, contains will not work on the optioncode.
You could do this if theyre the same reference or properly implemented valuetypes:
!OptionList.Contains(option)
or this if not:
!OptionList.Any(opt => opt.OptionCode == option.OptionCode)
your first query is wrong, you could change it to this...
where !rule.MustNotContainAllOptions.Any(option => OptionList
or use your 2nd query, which is correct

Get list of parent sub-type with all sub-type in LINQ

Using many Sub-Type tables with zero-one relation in C# code first!
public class MemberContractRelation
{
[Key]
public long Id { get; set; }
public long ContractId { get; set; }
public long MemberId { get; set; }
public long ListPrice { get; set; }
public decimal TaxCountryToPay { get; set; }
public decimal TaxProvinceToPay { get; set; }
public long InsuredCode { get; set; }
}
public class FamilyMemberContractSubtype : MemberContractRelation
{
public long CalculatedCheckupPrice { get; set; }
}
i want to getting list of my parent table (MemberContractRelation) with sub-type related record (like Left join) via this code :
var familyMemberContractSubtype = _rep.FamilyMemberContractSubtype.Where(a => a.Id == ContractId).Select(x => new
FamilyMemberInformationsBag
{
BirthDate = x.Member.BirthDate,
FirstName = x.Member.FirstName,
LastName = x.Member.LastName,
NationalID = x.Member.NationalCode,
PhoneNumber = x.Member.IranPhoneNumber,
Price = x.ListPrice,
ChekUpPrice = x.CalculatedCheckupPrice,
TotalPrice = x.ListPrice + x.CalculatedCheckupPrice + x.TaxProvinceToPay + x.TaxCountryToPay,
TaxProvinceToPay = x.TaxProvinceToPay,
TaxCountryToPay = x.TaxCountryToPay
}).ToList();
But it returns only records that have sub-Type and don`t return other records in MemberContractRelation!
I want to get a list of MemberContractRelation with sub-type and if it has not recorded in sub-type return Null value of property in sub-type!
remember I cant use any other solution for my project except above solution!
Assuming this is using EF TPT inheritance strategy (as it seems), first you should start the query from the parent (base) table:
// instead of _rep.FamilyMemberContractSubtype
// assuming _rep is DbContext
_rep.Set<MemberContractRelation>()
and then use operator as (important: not cast!) to access subtypes members, promoting non nullable types to nullable. In your sample:
ChekUpPrice = (long?)(x as FamilyMemberContractSubtype).CalculatedCheckupPrice
and
TotalPrice = x.ListPrice + x.TaxProvinceToPay + x.TaxCountryToPay +
((long?)(x as FamilyMemberContractSubtype).CalculatedCheckupPrice ?? 0)

entity framework when many to many is holding data

I'm using Entity Framework CTP5.
I have a schema like this:
A group contains many textdescriptions.
A textdescriptions has many texts.
A Language has many texts.
So there are 4 tables.
Groups one-to-many DEscriptions many-to-many Texts many-to-one Languages.
So I have a many-to-many relationship where the relation also holds data.
Definitions of Text and TextDescription ( since we can query on the Id for Group and Languages I havent added them here )
public class Text
{
public int TextID { get; set; }
public int TextDescriptionID { get; set; }
public int LanguageID { get; set; }
public string OriginalText { get; set; }
public bool IsValid { get; set; }
public DateTime Added { get; set; }
public DateTime Updated { get; set; }
public Language Language { get; set; }
public TextDescription TextDescription { get; set; }
public static Text GetMissingText(string input)
{
Text text = new Text();
text.OriginalText = "Missing: " + input;
text.IsValid = true;
text.TextDescription = new TextDescription()
{
IsStatic = true,
Name = input,
IsMultiline = false,
};
return text;
}
}
public class TextDescription
{
public int TextDescriptionId { get; set; }
public int TextDescriptionGroupId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool UseHtml { get; set; }
public bool IsMultiline { get; set; }
public bool IsStatic { get; set; }
public TextDescriptionGroup TextDescriptionGroup { get; set; }
public virtual ICollection<Text> Texts { get; set; }
public static TextDescription GetNewItem(int textDescriptionGroupId)
{
var item = new TextDescription();
item.Name = item.Description = "n/a";
item.UseHtml = item.IsMultiline = item.IsMultiline = false;
item.TextDescriptionGroupId = textDescriptionGroupId;
return item;
}
}
When adding either a new language or a new text is inserted ... the many to many relation is not inserted into the database. (Think it would be a bad idea, so in the end, if thats the only solution, I could be able to that)
So how do I handle this in a smart way when I need to fetch all the text for a specific group from the database, but also get the translation if there are one for that languages.
I can't start fra the translation object, since its possible its not there. If I start to query from the Text entity ... how do I only select one language without getting all languages first.
repo.Find(x =>
x.GroupId == groupId &&
x.Translation.Any(a => a.LanguageID == id.Value)
);
I'm lost here ... any there any smart way ... so I wont have to query the database for all the Texts ... and then a query for each item ... to see if there are a translation? or else just make a new empty one.
In SQL I would do it like this:
SELECT TD.Name, T.OriginalText FROM TextDescriptions TD
LEFT JOIN Texts T ON TD.TextDescriptionId = T.TextDescriptionId
WHERE TextDescriptionGroupId = 41 AND ISNULL(T.LanguageId, 1) = 1
The above SQL will give me the elements even if there is not record now, I get a NULL for these values. I could then handle that it my code and avoid lazy load.
But can I get the same behavior in Entity Framework. I could see there would be some problems maybe for EF4 to do the mapping ... since I'm going from TextDesciptions to Texts ... and TextDesciptions have a List of Texts ... but here ... I only want either 1 or NULL, or just a new Entity that havent been added to the database yet.
Looking forward to some interesting answers.
mvh
For now ... if no other solution is found I will be running the follow SQL script to insert empty records. This way I'm sure the record is there when a user wants to edit it and dont have to ensure its there before saving it. Maybe also avoiding some naste Linq query.
I only have to run this SQL 2 places. When adding a new Language or new a new TextDesciption.
INSERT INTO Texts
SELECT TD.TextDescriptionId, L.LanguageId, '', 0, GETDATE(), GETDATE(), L.TwoLetterISOLanguageName
FROM TextDescriptions TD
INNER JOIN Languages L ON 1 = 1
LEFT JOIN Texts T ON
T.TextDescriptionId = TD.TextDescriptionId AND
T.LanguageId = L.LanguageId
WHERE TextId IS NULL

Categories

Resources