Linq Query to Get Distinct Records from Two Tables - c#

I have two Tables - tblExpenses and tblCategories as follows
tblExpenses
ID (PK),
Place,
DateSpent,
CategoryID (FK)
tblCategory
ID (PK),
Name
I tried various LINQ approaches to get all distinct records from the above two tables but not with much success. I tried using UNION and DISTINCT but it didnt work.
The above two tables are defined in my Model section of my project which in turn will create tables in SQLite. I need to retrieve all the distinct records from both the tables to display values in gridview.
Kindly provide me some inputs to accomplish this task. I did some research to find answer to this question but nothing seemed close to what I wanted. Excuse me if I duplicated this question.
Here is the UNION, DISTINCT approaches I tried:
DISTINCT # ==> Gives me Repetitive values
(from exp in db.Table<tblExpenses >()
from cat in db.Table<tblCategory>()
select new { exp.Id, exp.CategoryId, exp.DateSpent, exp.Expense, exp.Place, cat.Name }).Distinct();
UNION # ==> Got an error while using UNION

I think union already does the distict when you join the two tables you can try somethin like
var query=(from c in db.tblExpenses select c).Concat(from c in
db.tblCategory select c).Distinct().ToList();

You will always get DISTINCT records, since you are selecting the tblExpenses.ID too. (Unless there are multiple categories with the same ID. But that of course would be really, really bad design.)
Remember, when making a JOIN in LINQ, both field names and data types should be the same. Is the field tblExpenses.CategoryID a nullable field?
If so, try this JOIN:
db.Table<tblExpenses>()
.Join(db.Table<tblCategory>(),
exp => new { exp.CategoryId },
cat => new { CategoryId = (int?)cat.ID },
(exp, cat) => new {
exp.Id,
exp.CategoryId,
exp.DateSpent,
exp.Expense,
exp.Place,
cat.Name
})
.Select(j => new {
j.Id,
j.CategoryId,
j.DateSpent,
j.Expense,
j.Place,
j.Name
});

You can try this queries:
A SELECT DISTINCT query like this:
SELECT DISTINCT Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;
limits the results to unique values in the output field. The query results are not updateable.
or
A SELECT DISTINCTROW query like this:
SELECT DISTINCTROW Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;<br/><br/>
looks at the entire underlying tables, not just the output fields, to find unique rows.
reference:http://www.fmsinc.com/microsoftaccess/query/distinct_vs_distinctrow/unique_values_records.asp

Related

C# Linq select all columns but alias a couple

I have the following query:
var list = (
from au in context.AnagraficaUtenti
join ut in context.Utenti on au.CodiceUtente equals ut.CodiceUtente into allcolumns
from entry in allcolumns
select entry
)
.ToList();
the problem is that both AnagraficaUtenti and Utenti have two columns called "Name" and "Surname", so the list I get contains only one of them. I would like to obtain a list of objects whose fields will be "NameAnagraficaUtenti", "SurnameAnagraficUtenti", "NameUtenti" and "SurnameUtenti" (among all the others).
Is that possible? Thank you.
P.S. I know that I can select fields one by one, by doing something like "new {field1 = field1, field2 = field2}", but I'd love if I could accomplish the same result with a general "select all", thank you.

Linq query without using Joins for two tables distinct value

Table 1
Contract ID , Vendor Name, Description , user
Table 2
Contract ID , product , department
Match condition : for all the Contract ID matching with table 1 , get their Vendor Name and Contract ID
Query result output :
Contract ID(Distinct),Vendor Name
Below code using inner join , need same output without using join as linq query
\\
select table1.Contract ID,table1.Vendor Name ,table2.Contract ID
from table1 as s1
inner join table2 as s2
on s1.Contract ID=s2.Contract ID
\\\
Thanks in Advance
Considering you need only Join alternative to select distinct ,you can use inner query logic like below to write LINQ
SELECT contractorid ,vendor name
Where
Contracterid in
(Select distinct contractor id from table2)
Here assumption is contractorId is primary key in table 1
If I understand correctly, you want to retrieve a collection of objects containing Contract Id and Vendor Names, without duplicates, whose Contract Id is found in Table 2.
It is unclear if you are using Linq to objects, Linq to Entities, or any other Linq flavor, which would have a meaningful impact on how to best construct a query for a specific purpose.
But as a first hint, here is a way to perform this without join with Linq:
// Get a list of all distinct Contract Ids in Table 2
var AllTable2ContractIds = Table2
.Select(e => e.ContractId)
.Distinct()
.ToList();
// With Table 1
// Keep only entries whose contract Id is found in the list just contructed above.
// transform it to keep Contract Id and Vendor Name.
// The use of ToList() at the end is not mandatory.
// It depends if you want to materialize the result or not.
var Result = Table1
.Where(e => AllTable2ContractIds.Contains(e.ContractId))
.Select(e => new
{
e.ContractId,
e.VendorName
})
.ToList();

Combining the results of two SQL queries

I have data in two tables and I need in one query get all data and join getting data.
SELECT
kpip.PersonalName,
kpiT.Name,
kpiPR.KpiTarget,
kpiPR.KpiResultDate,
kpiPR.KpiResult
FROM KpiPersonalResult AS kpiPR join KpiPersonal as kpip
on kpiPR.KpiPersonal = kpip.Id join KpiType AS kpiT
on kpip.KpiType = kpiT.Id join MerchantAdministrators as merA
on kpiPR.KpiAdded = merA.Id and kpiPR.KpiResultDate between '2021-04-07' and '2021-04-08'
select
kpiP.PersonalName,
kpiT.Name,
kpiP.KpiTarget
from KpiPersonal as kpiP join KpiType as kpiT
on kpiP.KpiType = kpiT.Id
Based on the fast that the second query has 3 columns of the same name as the first query, I guess you mean to union them:
SELECT
kpip.PersonalName,
kpiT.Name,
kpiPR.KpiTarget,
kpiPR.KpiResultDate,
kpiPR.KpiResult
FROM
KpiPersonalResult AS kpiPR
join KpiPersonal as kpip on kpiPR.KpiPersonal = kpip.Id
join KpiType AS kpiT on kpip.KpiType = kpiT.Id
join MerchantAdministrators as merA on kpiPR.KpiAdded = merA.Id and kpiPR.KpiResultDate between '2021-04-07' and '2021-04-08'
UNION ALL
select
kpiP.PersonalName,
kpiT.Name,
kpiP.KpiTarget,
null, --put suitable default values for the other columns here
null
from
KpiPersonal as kpiP
join KpiType as kpiT on kpiP.KpiType = kpiT.Id
Unioned queries need the same number of columns. I've inserted NULL as default value for the two missing columns in the second query (relative to the first)
UNION makes a resultset grow taller. If you intended for it to grow wider, that is done via JOIN. A simple pattern for doing so is:
WITH query1 AS(
--query 1 here
), query2 AS (
--query2 here
)
SELECT * FROM query1 JOIN query2 ON ...
Side note on formatting and indenting - most people find SQL most readable when all operations that are related are at the same indent level e.g in a typical query, the SELECT FROM WHERE GROUP ORDER keywords are all at the same indent level, with the blocks that relate to them (the list of selected columns, or list of joined tables, list of where'd predicates etc) indented a level again. We also typically don't use as when aliasing tables but we do use it when aliasing columns in the SELECT

Linq Multiple Joins

I have some sql tables that I need to query information from my current query that returns a single column list is:
from f in FactSales
where f.DateKey == 20130921
where f.CompanyID <= 1
join item in DimMenuItems
on f.MenuItemKey equals item.MenuItemKey
join dmi in DimMenuItemDepts
on item.MenuItemDeptKey equals dmi.MenuItemDeptKey
group f by dmi.MenuItemDeptKey into c
select new {
Amount = c.Sum(l=>l.Amount)
}
This returns the data I want and it groups correctly by the third table I join but I cannot get the Description column from the dmi table. I have tried to add the field
Description = dmi.Description
but it doesnt work. How can I get data from the third table into the new select that I am creating with this statement? Many thanks for any help.
Firstly you are using Entity Framework COMPLETELY WRONG. Linq is NOT SQL.
You shouldn't be using join. Instead you should be using Associations.
So instead, your query should look like...
from sale in FactSales
where sale.DateKey == 20130921
where sale.CompanyID <= 1
group sale by sale.Item.Department into c
select new
{
Amount = c.Sum(l => l.Amount)
Department = c.Key
}
By following Associations, you will automatically be implicitly joining.
You should not be grouping by the id of the "table" but by the actual "row", or in Object parlance (which is what you should be using in EF, since the raison d'etre of an ORM is to convert DB to Object), is that you should be grouping by the "entity" rather than they the "entity's key".
EF already knows that the key is unique to the entity.
The grouping key word only allows you to access sale and sale.Item.Department after it. It is a transform, rather than an operator like in SQL.

EF (LINQ to SQL) - How to query?

I have the concept of a document that has keyword/s. EF abstracted out the document-keyword joining table to an association.
The structure looks like this
Document: ID (PK)
Document_Keyword: DocumentID (PK), Keyword (PK)
Keyword: Keyword (PK)
I have the requirement to return a list of documents where they contain ALL keywords in a string[]
If I was doing this in SQL it would be similar to below
with t as (
select 'keyword1' KEYWORD union
select 'keyword2'
)
select DocumentID,count(*) from [dbo].[Document_Keyword] p
inner join t on p.KEYWORD = t.KEYWORD
group by DocumentID
having count(*) = (select count(*) from t)
Im struggling to form a linq query that will give me the same result.
I have tried the following LINQ statement however it does returns documents that contain 1 or more of the keywords in the array. I require that documents are only returned if ALL keywords match.
var query = (from k in db.KEYWORD
from b in k.DOCUMENT
join q in arrKeywords //array of string[]
on k.KEYWORD equals q
select new Document()
{
Filename = b.FILENAME,
Description = b.TITLE
});
Any ideas?
Cheers
Jeremy
If I get you well you want entries of which all keywords match exactly, i.e. it doesn't have any other keywords. A way too achieve this is
var kwc = arrKeywords.Count();
var query = from k in db.KEYWORD
let kw = k.DOCUMENT.Select(d => d.KEYWORD)
where kw.All(kw1 => arrKeywords.Contains(kw1))
&& kw.Count() == kwc;
The generated query is still much longer than a hand-coded one would be, but I think the database's query optimizer should be able to handle this.

Categories

Resources