Sql Multiple Conditions Method - c#

I've been trying to find a way of using multiple conditions with Sql, at the moment I am using Entity Framework. There is a very good chance that this is the only way to achieve what I want but I wondered if anyone knew a more efficient method.
Essentially I am using criteria to find the next row in the database which should be picked. For example lets use the 2 following conditions:
1) Field1 = A;
2) Field2 = B;
So in the following table:
| RowId | Field1 | Field2 |
| 0001 | A | B |
| 0002 | B | B |
| 0003 | C | C |
| 0004 | A | C |
I need to pick each row individually in the following order:
0001 - Both Condtions Satisfied,
0004 - Condition 1 Satisfied,
0002 - Condition 2 Satisfied,
0003 - No conditions satisfied
At the moment I am doing the following
public TestObj GetNextObj()
{
using (TestDb testDb = new TestDb())
{
TestObj testObj = (from o in testDb.TestTable
where o.Field1 == A && o.Field2 == B
select o).FirstOrDefault();
if (testObj != null)
return testObj;
testObj = (from o in testDb.TestTable
where o.Field1 == A
select o).FirstOrDefault();
if (testObj != null)
return testObj;
testObj = (from o in testDb.TestTable
where o.Field2 == B
select o).FirstOrDefault();
if (testObj != null)
return testObj;
testObj = (from o in testDb.TestTable
select o).FirstOrDefault();
return testObj;
}
}
This works okay, however I want to allow the conditions to be defined in a table and I am worried that when the number of conditions increases that this process will begin taking a very long time.
Is there another way to do what I am attempting here??
Thanks.
EDIT:::::
Now using the following code to select items from a table in order as defined by another table::
public static SortTest GetRow()
{
using (TestDb testDb = new TestDb())
{
SortParam[] sortParams = (from sp in testDb.SortParams
orderby sp.Priority ascending
select sp).ToArray();
if (sortParams.Length == 0)
{
SortTest sortTest = (from st in testDb.SortTests
orderby st.RowId ascending
select st).FirstOrDefault();
Console.WriteLine("Short route");
return sortTest;
}
Console.WriteLine("Long route");
StringBuilder sqlQueryBuilder = new StringBuilder();
sqlQueryBuilder.Append("SELECT * FROM [Proto].[dbo].[SortTests] ORDER BY \n");
foreach (SortParam sortParam in sortParams)
{
sqlQueryBuilder.Append("CASE WHEN " + sortParam.FieldName + " LIKE '%" + sortParam.FieldValue + "%' THEN 1 ELSE 2 END,\n");
}
sqlQueryBuilder.Append("\nRowId"); //By default use row Id
DbSqlQuery<SortTest> dbSqlQuery = testDb.SortTests.SqlQuery(sqlQueryBuilder.ToString());
return dbSqlQuery.FirstOrDefault();
}
}
I may have to alter thigns to prevent Sql Injection, but this works for now.
THANKS!

There's a simple way of doing it in a single query in SQL:
select *
from o
order by case Field1 when 'A' then 1 else 2 end,
case Field2 when 'B' then 1 else 2 end,
RowId

Related

Join with max time in EF Core C#

SELECT *
FROM Jobs j
WHERE j.InsertTime = (SELECT MAX(InsertTime) FROM Jobs)
How convert this SQL script to C# query?
I try this but not worked:
from j in _dbContext.Jobs
group j by j.InsertTime into g
select g.OrderByDescending(s=>s.InsertTime).First() into item
select item;
Sample data:
title | insertTime
------|-------------
AA | 2022-05-03
B | 2022-05-03
A | 2022-05-04
B | 2022-05-04
Result:
title | insertTime
------|-------------
A | 2022-05-04
B | 2022-05-04
Use the following query:
var query =
from d in _dbContext.Jobs.Select(d => new { d.Title }).Distinct()
from j in _dbContext.Jobs
.Wehere(j => j.Ttle == d.Ttle)
.OrderByDescending(j => j.InsertTime)
.Take(1)
select j;

I need to query table for values in two duplicate columns

I'm working in ASP.NET Core. I have a problem with querying rows which have same User_id and Definition_id, if there are any like that, I need ID of the row.
+----+---------+---------------+
| Id | User-id | Definition-id |
+----+---------+---------------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
| 4 | 3 | 1 |
| 5 | 4 | 1 |
| 6 | 4 | 1 |
| 7 | 5 | 2 |
| 8 | 6 | 1 |
+----+---------+---------------+
I need to query table like this, to return { 5, 6 } to me, because of them having same user AND definition ids.
I've tried Groupby for both values, but I can't get the IQueryable or IGrouping to give me the id of specific row.
I'd imagine it to work like that, but it ain't.
var placementsWithDuplicates =
from p in _context.Placements
group p by new { p.User_id, p.Definition_id } into what
select new
{
Id = what.Id,
User = what.User_id,
Defi = what.Definition_id,
};
foreach (var p in placementsWithDuplicates)
{
issues.Add(new IssueModel()
{
Type = "Praxe ID[" + p.Id + "]",
Name = "User id [" + p.User + "], Definition id [" + p.Defi + "]",
Detail = "So user shouldnt have data for more definitons!"
});
};
Thanks to Satish Hirpara for best answer, it needed a little update so I post the thing that ended up working well:
var B = from p in _context.Placements
group p by new { p.User_id, p.Definition_id } into what
where what.Count() > 1
select new
{
User_id = what.Key.User_id,
Definition_id = what.Key.Definition_id
};
var placementsWithDuplicates = from A in _context.Placements
join b in B on new { A.User_id, A.Definition_id } equals new { b.User_id, b.Definition_id }
select A;
Please find below SQL query:
SELECT A.*
FROM Placements A
INNER JOIN
(SELECT User_id, Definition_id FROM Placements
GROUP BY User_Id, Definition_id
HAVING COUNT(*) > 1) B
ON A.User_id = B.User_id AND A.Defination_id =
B.Defination_id
You can create a temp table to avoid join of sub query.
If you want linq query then I tried to create it from above query, please find it below:
--- sub query
var B = from p in Placements
group p by new { p.User_id, p.Definition_id } into what
where what.count() > 1
select new
{ User_id = what.User_id,
Definition_id =what.Definition_id
};
--- join
Var result = from A in Placements
Join B ON A.User_id = B.User_id
AND A.Defination_id = B.Defination_id
Select A
Please try this one.
Try This
var placementsWithDuplicates = from p in _context.Placements.Where(m => m.User_id == m.Definition_id)
select new {
Id = p.Id,
User = p.User_id,
Defi = p.Definition_id,
};
// this is same as the top one
var placementsWithDuplicates = from p in _context.Placements where p.User_id == p.Definition_id
select new {
Id = p.Id,
User = p.User_id,
Defi = p.Definition_id,
};
foreach (var p in placementsWithDuplicates)
{
issues.Add(new IssueModel()
{
Type = "Praxe ID[" + p.Id + "]",
Name = "User id [" + p.User + "], Definition id [" + p.Defi + "]",
Detail = "So user shouldnt have data for more definitons!"
});
};

dynamically bind data values into a repeater

I'm trying to bind the data values to a repeater, with bank names and balance of each bank. The balance is calculated as balance = sum(debit) - sum(credit), and i'm trying to get a result like:
-------------------
bank name | amount|
------------------|
a | 1200 |
------------------|
b | 1500 |
------------------|
c | 2400 |
-------------------
for this i used the code:
protected void bank_account()
{
var balance = 0;
using (var context = new sem_dbEntities())
{
var query = (from b in context.banks
join h in context.heads on b.h_id equals h.h_id
where b.bankstatus != 3 && (h.pid == 13 || h.h_id == 9)
select new { b.acc_name, b.h_id }).Take(4);
foreach (var item in query)
{
var debit1 = (from p in context.ledgers where p.h_id == item.h_id select p.debit).Sum();
var credit1 = (from q in context.ledgers where q.h_id == item.h_id select q.credit).Sum();
balance = Convert.ToInt32( debit1 - credit1);
var query1 = (from b in context.banks
join h in context.heads on b.h_id equals h.h_id
where b.bankstatus != 3 && (h.pid == 13 || h.h_id == 9)
select new { b.acc_name, b.h_id, balance }).Take(1);
foreach (var item1 in query1)
{
Repeater1.DataSource = query1.ToList();
Repeater1.DataBind();
}
}
}
}

Implementing COUNT() and ROUND() method in LINQ query

For another example to get return data of a pivot table I'm defined a LINQ query to solve this problem. Well, now my question is how to count the values of a column?
Here the following C# Code:
var query = from q in db.DS
where q.datum >= fromDate && q.datum <= toDate
group q by q.quot_rate
into grp
select new
{
Grade = grp.Key,
Total = grp.Select(t => new { t.fon, t.quot_rate }).AsQueryable()
};
var rate = (from q in db.DS
select q.fon).Distinct();
DataTable dt = new DataTable();
dt.Columns.Add("Grade");
foreach (var r in rate)
{
dt.Columns.Add(r.ToString());
}
foreach (var q in query)
{
DataRow dr = dt.NewRow();
dr["Grade"] = q.grade; //round q_grade
foreach (var t in q.Total)
{
dr[t.fon] = t.quot_rate; //count t.quot_rate
}
dt.Rows.Add(dr);
}
return dt;
You can see the comments where the numbers have to ROUND() and COUNT().
How can I define this?
EDIT:
The output is currently as follows:
Grade | AB001 | AB002 | AB003 ...
90,045| 90,045| null | null
85,590| null | 85,590| 85,590
85,450| null | 85,450| null
84,901| null | 84,901| null
and I want the result as follows:
Grade | AB001 | AB002 | AB003 ...
90 | 1 | 0 | 0
86 | 0 | 1 | 1
85 | 0 | 2 | 0
So it appears that you actually want rounding to happen inside the query, so that you can do grouping by rounded values. So first part of the question can be answered as:
Grade = Math.Round(grp.Key),
Then the counts come out naturally as:
q.Total.Count()
However it seems that you actually want counts by rate items, so I would suggest something like that for each table row:
foreach (var r in rate)
{
dr[r] = q.Total.Count(x => x.fon == r);
}

How to find the min dates from the list of items?

I have a table structure like this
id | itemId | date |
1 | a1 | 6/14/2015
2 | a1 | 3/14/2015
3 | a1 | 2/14/2015
4 | b1 | 6/14/2015
5 | c1 | 6/14/2015
From this table structure I am trying to get all the distinct items that has min date. for e.g. I am trying to get id = 3,4 and 5.
I have tried following code but I couldn't
var items = (from i in _db.Items
//where min(i.date) // doesn't seem right
group i by i.itemID
into d select new
{
iId = d.Key,
}).Distinct();
Given your sample data, I would do this:
var query =
from i in _db.Items
group i by i.itemId into gis
let lookup = gis.ToLookup(x => x.date, x => x.id)
from x in lookup[gis.Min(y => y.date)]
select x;
var items = from i in _db.Items
group i.date by i.itemID
into d select new {
iId = d.Key, iDate = d.Min()
};

Categories

Resources