querying key value pair design table using EF - c#

I have a table which is similar to Key-Value pair design structure. I would like to query the table based on the key and value, but I am facing some problem. Below is my table structure and expected output.
Table 1:
ID KEY VALUE
1 NAME abc
2 AGE 12
3 DEPARTMENT CCB
4 NAME xyz
5 AGE 13
6 DEPARTMENT TSS
7 NAME cde
8 AGE 12
9 DEPARTMENT TMS
Table 2:
KeyId KeyName
1 Name
2 Department
3 Age
for easy understanding I entered directly the key names in Table 1, actually there exists a foreign key relation between table 1 and table 2.
Also table 2 can hold anything as KeyName not necessarily Name, Department and Age.
Expected output is : I need to get the data with the Name contains %c% and Age = 12.
Name Age Department
abc 12 CCB
cde 12 TMS
NOTE: I am looking for a EF solution i.e., linq query, not sql query.
Options I tried out, below is the query:
var temp = (from c in table1
where c.Name.Contains("C") || C.Age == 12
Select new { C.Name, C.Age })
Thought of applying "OR" condition so that I get both the condition satisfied and then filter using "AND" in the in-memory once I fetch the data from database. But I was not able to succeed.

Try this:
var result = input.Select((x,i)=>new {x,i})
.GroupBy(a=>a.i/3)
.Where(g=>g.FirstOrDefault().x.Value.Contains("c") &&
Convert.ToInt32(g.Skip(1).FirstOrDefault().x.Value) == 12)
.Select(g=> new {
Name = g.FirstOrDefault().x.Value,
Age = Convert.ToInt32(g.Skip(1).FirstOrDefault().x.Value),
Department = g.Skip(2).FirstOrDefault().x.Value
});
Not sure if it works in EF but looks like if it doesn't, you have to execute the query in client side with AsEnumerable() before appending any method after input.

Related

Select items with the same foreign key

I have a question regarding Linq in C#.
Let's say that I have 3 tables "Company", "Employee" and "Job".
Company
--------
Id - int (PK)
Name - string
Employee
--------
Id - int (PK)
CompanyId - int (FK on Company.Id)
Name - string
Job
--------
Id - int (PK)
CompanyId - int (FK on Company.Id)
EmployeeId - int (FK on Employee.Id)
Name - string
Something like that:
enter image description here
The important thing is that every work must be connected to a company but not necessarily to an employee. However, each employee must be connected to a company. For example we can have racord like that:
Company
--------
Id Name
1 'A'
2 'B'
3 'C'
Employee
--------
Id CompanyId Name
1 1 'A'
2 1 'B'
3 2 'C'
Job
--------
Id CompanyId EmployeeId Name
1 1 1 'clean'
2 1 2 'wash'
3 2 2 'buy'
4 3 NULL 'sell'
And now with linq I would like to get all jobs that are assigned to this employee and other employees from the same company.
So in this case it will should are jobs with id 1 and 2 becouse employee 1 is assigned to company 1 and job with id 2 also has assigned to this company. How could I achieve this using linq but something like this:
_context.Job.Where (x => x)
It is important to make only one query to the database.
Tkanks.
You can simplify the problem by thinking of it in two steps: find the company for a given employee, find all the jobs for that company:
var companyToFind = from e in Employee
where e.Id == empToFind
select e.CompanyId;
var jobsToFind = from j in Job
where companyToFind.Any(cid => cid == j.CompanyId)
select j;
In LINQ to SQL, EF Core 2.2 and EF Core 3.x the Any is translated to an EXISTS query in SQL.
Note since you know there should be only one answer to companyToFind, sending two queries to the database may be more efficient.
For LINQ to SQL or EF Core 3.x, you could also nest the first query and reduce to a single result:
var jobsToFind = from j in Job
where (from e in Employee
where e.Id == empToFind
select e.CompanyId).First() == j.CompanyId
select j;

Algorithm: two tables are in connection with ID, calculating a new table from them

I have two Excel tables for input.
The structure of the first one is like (first_table, fields: id, value, no primary key):
ID1 4
ID1 5
ID1 2
ID2 3
ID2 1
ID3 1
ID4 1
ID4 3
etc till the end of the document (it's not determined)
The second one is like (second_table, fields: id, value, ID is primary key):
ID1 2
ID2 5
ID3 1
ID4 2
etc till the end of the document (it's not determined)
I would like to create a new table (let's call it output_table) from these. The new table should contain the same fields: ID and value. In this new table I want to write each records from the first table keeping its sequence (it's very important, because it's in a timeline). The values should change according to the following conditions:
- ID's are in connection
- if the first_table.value is higher than or equals with the second_table.value, the output.value := second_table.value. And this point I would like to omit records under it with the same IDs (in the first table) and step to the next ID type.
- if the the second_table.value is higher than the first_table.value, then output_table.value := first_table.value and the reference of second_table.value := (second_table.value - first_table.value) for the next step (and if this case happens, I want to investigate the next record with the calculated reference till a new ID comes up from first_table, or the first condition will be true)
I could not figure out the proper algorithm for it, please help me! Thank you for your help!!
I'm working in C#, and I have already created list of (record) objects from the two input table. (so maybe Linq would help me)
ok.
You may create a class (you could use a Tuple<string, int> instead, but it maybe easier to understand) for first_table and output table values.
public class MyDatas {
public string Id {get;set;}
public int Value {get;set;}
}
Imagine you have, from first_table, a List of MyDatas
And for second_table a Dictionary<string, int>
which seems reasonable.
then you create an empty list of MyDatas which is your output.
var table1 = new List<MyDatas>(<content of first_table>);
var table2 = new Dictionary<string, int>(<content of second_table>);
var output = new List<MyDatas>();
//good old foreach, this may be clearer than linq in this case.
foreach (var l1 in table1) {
var id = l1.Id;
//default : we take table 1 Value (if Id is not in table2 or table 2 value > table1 value
var newData = new MyDatas{Id = id, Value = l1.Value};
output.Add(newData);
//id of table1 is not in table 2, go to next line.
if (!table2.ContainsKey(id)) continue;
//if table 1 value > = table 2 value => take table 2 value
if (l1.Value >= table2[id])
newData.Value = table2[id];
//if table 2 value => table 1 value, keep table 1 value for output and decrement table2 value
else {
table2[id] -= l1.Value;
}
}

Duplicate Records when they should be unique

I have a table that I'm trying to query using Linq to SQL
The table is very simple it has 5 columns:
- PersonID
- ADID
- Name
- PlaceID
- PlaceName
I have 2 records in my table and they have the same PersonID in both records but different PlaceID and PlaceName values:
001 | 001 | Person X | P01 | Place 1
001 | 001 | Person X | P02 | Place 2
When I query this in SQL I get exactly the 2 rows:
select * from myTable where PersonID = '001'
However, when I try to do it in LINQ:
List<myTable> PersonInfo = (from myInfo in db.myTable
where myInfo.PersonID == "001"
select myInfo).ToList();
I get a count of 2 in PersonInfo but they are the same record. What am I doing incorrectly?
What I found out was that 1st Entity Framework needs a primary key to operate correctly. After researching the table I was using I found out that there was a primary key but it was a combo key So once I put "Entity Keys" on both columns my select statement returned the correct data.
Thanks to #GertArnold and everyone else that helped me on this problem!

SQL query to get matching records from Table1 and Table2 with a custom column showing 1/0 if data is present

I have several table related to multilingual Photo Galley like
AlbumCategories
AlbumName
Photos
PhotoDetails
Sample Table Structure of two table. I actually want a result set that will show me list of all records from Photos Table for particular AlbumID along with a custom column that will show TRUE or FALSE based on if particular PhotoID is present in the PhotoDetails Table
Table: Photos
PhotoID PhotoFile AlbumID
1 Photo1.jpg 7
2 Photo2.jpg 7
3 Photo3.jpg 5
4 Photo4.jpg 5
5 Photo5.jpg 7
6 Photo6.jpg 7
Table: PhotoDetails
PDID PhotoID PDTitle AlbumID LanguageID
11 1 Photo 1 7 1
22 2 Photo 2 7 1
33 3 Photo 3 5 1
44 4 Photo 4 5 1
DESIRED OUT PUT
PhotoID PDTitle AlbumID DetailPresent
1 Photo1 7 TRUE
2 Photo2 7 TRUE
5 Photo5 7 FALSE
6 Photo6 7 FALSE
I tried something several JOIN based queries but could not get the desired result
SELECT pd.PhotoTitle, p.PhotoTN,p.PhotoCreatedOn, pd.AlbumID, ISNULL(p.PhotoID,NULL) AS Missing FROM AlbumPhotos p
JOIN AlbumPhotoDetails pd
ON p.PhotoID = pd.PhotoID WHERE pd.AlbumID = 16
This query gives me the same result
SELECT pd.PhotoTitle, p.PhotoTN,p.PhotoCreatedOn, pd.AlbumID, ISNULL(p.PhotoID,NULL) AS Missing FROM AlbumPhotos p
JOIN AlbumPhotoDetails pd
ON p.PhotoID = pd.PhotoID WHERE pd.AlbumID = 16
OR p.PhotoID IN (SELECT PhotoID FROM AlbumPhotoDetails WHERE LanguageID = 1 AND AlbumID = 16)
Above query get me the result of matching based on PhotoID. I am lost how i can actually achieve the desired result as shown in the above sample 'DESIRED OUT PUT`
Use a left outer join.
The table examples that you have shown doesn't make any sense, as there is no field to connect them, and the PDTitle values that you want in the result doesn't exist in the example data.
Assuming that there is a PhotoId field in the PhotoDetails table (like in the AlbumPhotoDetails table that you use in the query that you show), and that the PhotoDetails table contains the titles that you want in the result, you can do like this:
select
p.PhotoId, d.PDTitle, p.AlbumId,
case when d.PhotoId is null then 'FALSE' else 'TRUE' end
from Photos p
left join PhotoDetails d on d.PhotoId = p.PhotoId
where p.AlbumId = 7
Note that the title will be null where there are no corresponding record in the PhotoDetails table.

Get Data from MS Access Database into List<> in C#

Current now i have a List<> of data store string called Diff_ProductName.
List<string[]> Diff_ProductName = ("SELECT GUID,ProductName FROM Table_A bla bla bla.... ");
So i need to use GUID from Diff_ProductName to copy another data from another Table.
For (int i = 0; i < Diff_ProductName; i++)
{
List<string[]> DCB_CopyData = ("SELECT Name, ID FROM Table_B WHERE='"+(((string[])Diff_ProductName[i])[0]+"'");
}
The problems is, every GUID got a few ID and Name. Mean :
TABLE_B
GUID Name ID
1 A 012
1 B 013
1 c 014
2 AB 015
3 D 016
3 E 017
4 ACE 018
4 ADE 019
so when i run the program. The data store at DCB_CopyDate only the last GUID data. Mean at DCB_CopyData only have :
GUI Name ID
4 ACE 018
4 ADE 019
So whats the problems with my code? thanks.
You are executing a query for each GUID and this is painful if your list is really long.
You could simply execute one query like this
SELECT ta.*, tb.* FROM Table_A AS ta
LEFT JOIN Table_B AS tb ON ta.GUID = tb.GUID
About your code: if you're showing us pseudo-code ok, if not your second query seems really wrong sintactically.

Categories

Resources