I bind two columns into a dropdown using SQL like this
string query = "Select Id,Name+':'+Distribution_name+' 'as Name1 from BR_supervisor where( (id not in (select SupId from tbluser where active='true')) and active='true' ) ";
DropDownList3.DataTextField = "Name1";
DropDownList3.DataValueField = "Id";
DropDownList3.DataBind();
Now I want to transform my query into linq expression and bind the dropdown. How to do this?
var query = from s in db.BR_supervisor
join u in db.tbluser.Where(x => x.active)
on s.id equals u.SupId into g
where s.active && !g.Any()
select new {
s.Id,
Name1 = s.Name + ":" + s.Distribution_name
};
DropDownList3.DataTextField = "Name1";
DropDownList3.DataValueField = "Id";
DropDownList3.DataSource = query;
DropDownList3.DataBind();
This generates SQL like:
SELECT [t0].[Id], ([t0].[Name] + #p0) + [t0].[Distribution_name] AS [Name1]
FROM [BR_supervisor] AS [t0]
WHERE ([t0].[active] = 1) AND (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [tbluser] AS [t1]
WHERE ([t0].[id] = [t1].[SupId]) AND ([t1].[active] = 1)
)))
var query2 = (from a in this._projectDataContx.BR_Supervisors
where ((!(from x in this._projectDataContx.tblUsers
where (x.Active == true)
select x.SupId).Contains(a.Id))&&(a.Active==true))
select new { Name1 = a.Name + ":" + a.Distribution_Name, a.Id });
DropDownList3.DataSource = query2;
DropDownList3.DataTextField = "Name1";
DropDownList3.DataValueField = "Id";
DropDownList3.DataBind();
Related
Good day, everyone!
I'm working on a c# test automation script, and I have a sql query that returns a few values based on a few checks with cast, Case When, and Sum - but now we need to transfer it to Entity Framework as a linq query, and I'm not sure how to do so.
Could someone please assist me with this?
Here is my sql query
SELECT
co.orderId AS OrderId
,(SELECT
COUNT(*)
FROM ci_orders (NOLOCK) co
INNER JOIN Customer (NOLOCK) cust
ON cust.IdCustomer = co.customerId
WHERE cust.Email = c.Email
AND co.PaymentTransactionStatusID = 1)
AS CustomerOrdersCount
,co.PitStopStatus AS PitStopStatus
,(SELECT
SUM(ops.Price + ops.QuantityDiscount)
FROM OrderProductSelect (NOLOCK) ops
WHERE ops.OrderId = 2257327)
AS NetPrice
,CAST(CASE WHEN Exists (SELECT
oi.Id
FROM OrderIssues (NOLOCK) oi
LEFT JOIN PitStops ps
ON ps.Id = oi.PitStopId
WHERE oi.OrderId = co.orderId
AND IssueType = 'HighValueOrder') THEN 1
ELSE 0 END AS BIT)
AS IsHighValuePitStop
FROM ci_orders (NOLOCK) co
INNER JOIN Customer (NOLOCK) c
ON c.IdCustomer = co.customerId
WHERE co.orderId =2257327
#eldar - I tried below way
using (var context = GetDbContext())
{
var yellowOrder = context.YellowOrders.FirstOrDefault(x => x.OrderId == orderId);
var result = (from co in context.Orders
join c in context.Customers
on co.customerId equals c.IdCustomer
where co.orderId == orderId
select new
{
OrderId = orderId,
IsHighValuePitStop = (from oi in context.OrderIssues
join ps in context.PitStops
on oi.PitStopId equals ps.Id
where oi.OrderId == orderId && ps.IssueType == "HighValueOrder")
}).Any();
return yellowOrder != null;
}
You can achieve Case When in linq with a ternary (?:) operator. And since your queries are mostly inner selects your linq should look like this :
var result = await (
from co in context.ci_orders
join c in context.Customers on co.customerId eqals c.IdCustomer
where co.orderId =2257327
select new { // here your inner selects go
OrderId = co.orderId,
IsHighValuePitStop = (from oi in context.OrderIssues
join ps in context.PitStops on oi.PitStopId equals ps.Id
where oi.OrderId = co.orderId and oi.IssueType = 'HighValueOrder').Any(), // you could use ternary operator but Any already returns a boolean value ? true : false would be meaningless
NetPrice = context.OrderProductSelect.Where(r=> r.OrderId = 2257327).Sum(ops=> ops.Price + ops.QuantityDiscount),
co.PitStopStatus,
CustomerOrdersCount = (from co in context.ci_orders
join cust context.Customer on co.customerId equals cust.IdCustomer
where cust.Email = c.Email
&& co.PaymentTransactionStatusID = 1
select co).Count()
}).ToArrayAsync()
I have created a WPF form with checkbox. If checkbox is checked I would like to compare data by two columns and if it is not checked only by one.
Below code is working fine but I am not sure I am doing it the best way possible?
Question: Is below code the right way to go for if statement? Are there better solutions?
Here is the code for if statement:
IEnumerable<JoinedFIandSE> firstPart;
IEnumerable<JoinedFIandSE> secondPart;
if (MainWindow.CompareByTwoColumnsYes == true)
{
firstPart = from table1 in t2.AsEnumerable()
join table2 in t1.AsEnumerable()
on new { A = (string)table1["SNAME"], B = (string)table1["NAMEB"] } equals
new { A = (string)table2["SNAME"], B = (string)table2["NAMEB"] } into temp
from table2 in temp.DefaultIfEmpty()
select new JoinedFIandSE
{
NRO = (string)table1["NRO"],
NRO1 = table2 != null ? (string)table2["NRO"] : string.Empty,
SNAME = (string)table1["SNAME"],
NAMEA = (string)table1["NAMEA"],
NAMEB = (string)table1["NAMEB"],
};
}
else
{
firstPart = from table1 in t2.AsEnumerable()
join table2 in t1.AsEnumerable()
on (string)table1["SNAME"] equals (string)table2["SNAME"] into temp
from table2 in temp.DefaultIfEmpty()
select new JoinedFIandSE
{
NRO = (string)table1["NRO"],
NRO1 = table2 != null ? (string)table2["NRO"] : string.Empty,
SNAME = (string)table1["SNAME"],
NAMEA = (string)table1["NAMEA"],
NAMEB = (string)table1["NAMEB"],
};
}
I am doing the same for another table and then
var results = firstPart.Concat(secondPart);
return results;
This code is inside public static IEnumerable<JoinedFIandSE> GetMyJoinedResult() method.
You can try this, it will just move your condition into join clause.
IEnumerable<JoinedFIandSE> firstPart;
IEnumerable<JoinedFIandSE> secondPart;
firstPart = from table1 in t2.AsEnumerable()
join table2 in t1.AsEnumerable()
on new { A = (string)table1["SNAME"], B =
MainWindow.CompareByTwoColumnsYes ? (string)table1["NAMEB"]: "" } equals
new { A = (string)table2["SNAME"], B = MainWindow.CompareByTwoColumnsYes ? (string)table2["NAMEB"]: "" } into temp
from table2 in temp.DefaultIfEmpty()
select new JoinedFIandSE
{
NRO = (string)table1["NRO"],
NRO1 = table2 != null ? (string)table2["NRO"] : string.Empty,
SNAME = (string)table1["SNAME"],
NAMEA = (string)table1["NAMEA"],
NAMEB = (string)table1["NAMEB"],
};
There could be a more better solution for this.
So, I'm trying to build a code generator that will extract indexes from a database and make a class that will filter based on an index.
Below code works in SQL-server and yields 2 records. But my SqlDataReader yields zero records.
Provided example for 1 table with index.
Hoping someone can help me out here.
Code in SQL server:
create table Agent(
ID bigint constraint PK_Agent primary key identity(1,1),
LastName nvarchar(50) not null,
FirstName nvarchar(50) not null,
index IN_Agent_Name nonclustered (LastName, FirstName)
)
select t.object_id,
s.name as schemaname,
t.name as tablename,
i.index_id,
i.name as indexname,
index_column_id,
c.name as columnname
from sys.tables t
inner join sys.schemas s on t.schema_id = s.schema_id
inner join sys.indexes i on i.object_id = t.object_id
inner join sys.index_columns ic on ic.object_id = t.object_id and ic.index_id = i.index_id
inner join sys.columns c on c.object_id = t.object_id and ic.column_id = c.column_id
where i.index_id > 0
and i.type in (1, 2)
and i.is_primary_key = 0
and i.is_unique_constraint = 0
and i.is_disabled = 0
and i.is_hypothetical = 0
and ic.key_ordinal > 0
and t.name like 'Agent'
and i.name like 'IN_Agent_Name'
Code in VS:
public static TableIndex GetIndex(string indexName, string tableName)
{
TableIndex index = null;
using (var conn = new SqlConnection("Server=localhost;Database=VenturaERD;User Id=VenturaDBUser;Password = Ventura;"))
{
conn.Open();
var cmd = new SqlCommand("select t.object_id, s.name as schemaname, t.name as tablename, i.index_id, i.name as indexname, index_column_id, c.name as columnname from sys.tables t inner join sys.schemas s on t.schema_id = s.schema_id inner join sys.indexes i on i.object_id = t.object_id inner join sys.index_columns ic on ic.object_id = t.object_id and ic.index_id = i.index_id inner join sys.columns c on c.object_id = t.object_id and ic.column_id = c.column_id where i.index_id > 0 and i.type in (1, 2) and i.is_primary_key = 0 and i.is_unique_constraint = 0 and i.is_disabled = 0 and i.is_hypothetical = 0 and ic.key_ordinal > 0 and t.name like '" + tableName + "' and i.name like '" + indexName + "'")
{
Connection = conn
};
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
index = new TableIndex()
{
TableId = reader.GetInt32(reader.GetOrdinal("object_id")),
TableName = reader.GetString(reader.GetOrdinal("tablename")),
IndexId = reader.GetInt32(reader.GetOrdinal("index_id")),
IndexName = reader.GetString(reader.GetOrdinal("indexname")),
Columns = new List()
{
new IndexColumn()
{
ColumnName = reader.GetString(reader.GetOrdinal("columnname")),
Order=reader.GetInt32(reader.GetOrdinal("index_column_id"))
}
}
};
while (reader.Read())
{
index.Columns.Add(new IndexColumn()
{
ColumnName = reader.GetString(reader.GetOrdinal("columnname")),
Order = reader.GetInt32(reader.GetOrdinal("index_column_id"))
});
}
}
reader.Close();
}
}
return index;
}
Please check the users rights, I believe with only the public rights the user will not get any data.
Make sure the user you are connecting to with SQL management studio and the user in the connection string are the same.
The user (in my tests at least) needs at least the db_datareader role.
I have an SQL query that displays information from different tables in the database. This query is then displayed in a DataGrid and I have some options in a DropDownList to search through the DataGrid for certain values. The problem is the search doesn't display the correct information for CollectName or DeliverName.
Code for DropDownList:
private static readonly Dictionary<string, string> SearchFields = new Dictionary<string, string> {
{ "Customer", "c.Name" },
{ "Department", "jn.Department" },
{ "CollectName", "SELECT Name FROM job_address WHERE AddressType = 3 AND JobID = jn.ID" },
{ "DeliverName", "(SELECT Name FROM job_address WHERE AddressType = 2 AND JobID = jn.ID)" }
};
In the SQL query CollectName and DeliverName are inner select statements and that's whats causing the problem here because the search for Customer and Department work fine.
The SQL query:
SELECT c.Name,
COUNT(distinct jn.ID) as Jobs,
sum(jn.OutTurn) as Outturn,
SUM(jn.ActualWeight) as GrossWt,
SUM(jn.CBM) as CBM,
jn.Department,
(SELECT Name FROM job_address WHERE AddressType =3 AND JobID = jn.ID) as CollectName,
(SELECT Name FROM job_address WHERE AddressType =2 AND JobID = jn.ID) as DeliverName
FROM customer c
LEFT JOIN job_address ja ON c.AccountCode = ja.Code AND c.Company_ID = ja.Company_ID
JOIN AddressType jat ON ja.AddressType = jat.ID and jat.Description = 'Debtor'
LEFT JOIN job_new jn ON ja.JobID = jn.ID
WHERE c.Company_ID = ?compid
GROUP BY c.ID
I have a search function that takes the value selected from the DropDownList and the value entered in the textbox:
List<MySqlParameter> param = new List<MySqlParameter>{ new MySqlParameter("compid", CompanyID) };
StringBuilder SQL = new StringBuilder(SearchSQL);
if (SearchFieldKey != null && SearchFieldKey.Length > 0)
{
SQL.Append(" AND (");
for (int i = 0; i < SearchFieldKey.Length; i++)
{
if (SearchFields.ContainsKey(SearchFieldKey[i]))
{
SQL.Append(SearchFields[SearchFieldKey[i]] + " LIKE ?parameter" + i.ToString());
param.Add(new MySqlParameter("parameter" + i.ToString(), "%" + SearchTerms[i] + "%"));
if (i != SearchFieldKey.Length - 1)
SQL.Append(" OR ");
}
else
throw new Exception("Error: Attempted to search on invalid field. Check SearchFields Argument.");
}
SQL.Append(") ");
}
So for example I search for a customer, the SQL query get this line added to end:
WHERE c.Company_ID = ?compid AND (c.Name LIKE ?parameter0)
And when I search for CollectName or DeliverName the query is this:
WHERE c.Company_ID = ?compid AND (SELECT Name FROM job_address WHERE AddressType = 3 AND JobID = jn.ID LIKE ?parameter0)
Is there a problem with this SQL query that causes CollectName and DeliverName not to work?
The parenthesis doesn't match, it should be
WHERE c.Company_ID = ?compid
AND (SELECT Name FROM job_address WHERE AddressType = 3 AND JobID = jn.ID) LIKE ?parameter0
To solve this, you can in your dictionary embed the statement:
{ "CollectName", "(SELECT Name FROM job_address WHERE AddressType = 3 AND JobID = jn.ID)" },
Or in your method that build the SQL, embed automatically the subquery:
SQL.Append("(" + SearchFields[SearchFieldKey[i]] + ") LIKE ?parameter" + i.ToString());
Full correction : you should not try to concatenate string together if you are using a StringBuilder:
var param = new List<MySqlParameter> { new MySqlParameter("compid", CompanyID) };
StringBuilder SQL = new StringBuilder(SearchSQL);
if (SearchFieldKey != null && SearchFieldKey.Length > 0)
{
SQL.Append(" AND (");
for (int i = 0; i < SearchFieldKey.Length; i++)
{
if (SearchFields.ContainsKey(SearchFieldKey[i]))
{
SQL.Append("(");
SQL.Append(SearchFields[SearchFieldKey[i]]);
SQL.Append(") LIKE ?parameter");
SQL.Append(i);
param.Add(new MySqlParameter("parameter" + i.ToString(), "%" + SearchTerms[i] + "%"));
if (i != SearchFieldKey.Length - 1)
SQL.Append(" OR ");
}
else
throw new Exception("Error: Attempted to search on invalid field. Check SearchFields Argument.");
}
SQL.Append(") ");
}
What would be the Linq expression equivalent of the following TSQL query:
SELECT c.[CustomerId]
,c.[Name]
, (SELECT COUNT(*) FROM Incidents WHERE CustomerId = c.CustomerId) AS IncidentsCount
, (SELECT COUNT(*) FROM Opportunities WHERE CustomerId = c.CustomerId) AS OpportunitiesCount
, (SELECT COUNT(*) FROM Visits WHERE CustomerId = c.CustomerId) AS VisitsCount
FROM [Customers] c
I haven't double-checked this in visual studio but this should work:
var x = (from c in Context.Customers
select new {
CustomerId = c.CustomerId,
Name = c.Name,
IncidentsCount =
Context.Customers.Count(i => i.CustomerId == c.CustomerId),
OpportunitiesCount =
Context.Opportunities.Count(o => o.CustomerId == c.CustomerId),
VisitsCount =
Context.Visits.Count(v => v.CustomerId == c.CustomerId)
});
Update: I changed the code to be a little bit easier to read.