SQL table result command in textbox instead of the result in C# - c#

Here is the table setup I have:
int | Design_1
0 | Design_A
1 | Design_B
2 | Design_C
Here is my code for the form:
var design = (from d in BikePartsDataContext1.handlebars
where d.#int == "0"
select d.Design_1);
this.textBox1.Text = design.ToString();
What I am trying to do is make the textBox1 text have the value of the Design_1 value from the row where #int is 0.
All works fine until I get this as the text value for textBox1:
SELECT [t0].[Design 1] FROM [dbo].[handlebars] AS [t0] WHERE [t0].[int] = #p0

I think you want the first record then based on Id?
// at top of file so you can use the extension methods
using System.Linq;
// code
var design = (from d in BikePartsDataContext1.handlebars
where d.#int == 0 // i removed the quotes add them back if this is truely a string/sql varchar
select d.Design_1).Single(); // use single to ensure only 1 record will get selected
this.textBox1.Text = design; // design will now be the value of Design_1
Some notes:
Single will throw an exception if no records are found OR if more than one record is found.
If there can be 0 records use SingleOrDefault
If there can be more than 1 record and you do not care which one is used then use First or FirstOrDefault
I assumed your id was an int and not a string so I removed the quotes around 0, add them back if this is not the case
You can also rewrite it using only lambda expressions:
this.textBox1.Text = BikePartsDataContext1.handlebars
.Where(x => x.#int == 0)
.Select(x => x.Design_1)
.Single();

Related

Self join in LINQ

SELECT
FW1.id, count(*)
FROM
firmware FW1
LEFT JOIN
firmware FW2 ON FW1.firmware_group_id = FW2.firmware_group_id
AND FW1.br_date < FW2.br_date
AND FW2.[public]= '1'
GROUP BY
FW1.id
I am looking to convert into linq query. As I know less than symbol cannot be converted into Linq query. Please suggest how to do it. I have a string date and I need to compare into linq.
As you said, Linq does not support other types of join outside of EquiJoin. Docs is pretty clear on what you can do to bypass this:
you could use a simple cross join (a cartesian product), then applying in the where clause the conditions for your non-equijoin.
Or you could use a temporary variable to store a new table with only the attributes you need for your query and, like before, applying the conditions in the where clause.
In your case, a possible Linq query could be this one:
from f1 in firmwares
from f2 in firmwares
let f1_date = DateTime.Parse(f1.Dt)
let f2_date = DateTime.Parse(f2.Dt)
where f1.Group_Id == f2.Group_Id && f1_date < f2_date
group f1 by f1.Id into fres
select new {
Id = fres.Key,
Count = fres.Count()
};
However I am still thinking how to emulate the LEFT JOIN without casting it to a group join.
Of course the < symbol can be used. Just use method syntax instead of query syntax!
Every FW1 has zero or more FW2s. Every FW2 belongs to exactly one FW1. This one-to-many is implemented using foreign key firmware_group_id.
Apparently you want all FW1s, each with the number of its FW2s, that have a property public with a value equal to 1 and a property br-date larger than the value of the br-date of the FW1.
Whenever you want an item with its many sub-items (using a foreign key), like s School with its Students, a Customer with his Orders, a Book with his Pages, you'll need Enumerable.GroupJoin
var result = FW1.GroupJoin(FW2, // GroupJoin FW1 and FW2
fw1 => fw1.firmware_group_id, // from fw1 take the primary key firmware_group_id
fw2 => fw2.firmware_group_id, // from fw2 take the foreing key firmware_group_id
(fw1, fw2s) => new // from every fw1, with all its matching fw2s
{ // make one new object containing the following properties:
Id = fw1.Id,
// Count the fw2s of this fw1 that have public == 1
// and a date larger than fw1.date
Count = fw2.Where(fw2 => fw2.Public == 1 && fw1.br_date < fw2.br_date)
.Count(),
});
Note:

Add a Lambda in a LINQ query to replace a line in a foreach

I have a situation where I have to match up multiple customers numbers from one system with a single customer number in another system.
So for instance customer number 225, 228 and 223 in system A will all map to customer number 110022 in system B.
Easy enough, I have a matrix setup to do that.
I pull the matrix data in like this:
 var dt_th_matrix = (from m in aDb.Matrix_Datatrac_TopHat select m).ToArray();
So the records would be something like:
customerA: 3 CustomerB: 1001
CustomerA: 4 CustomerB: 1001
CustomerA: 5 Customer: 1002
Then I do a big data pull and step through all the items. For each of the items I go grab the matching customer number from the matrix like this:
foreach (var dt_stop in mainPull)
{
int? th_customerId = (from d in dt_th_matrix
where d.datatrac_customer_no == dt_stop.Customer_No.ToString()
select d.tophat_customer_detail_Id).First();
What I would rather do is to just embed the code to grab the customer numbrer from the matrix directly in my datapull -- the part "Query goes here somehow" will be some type of Lambda I assume. Any help?
I have tried something like this:
th_customerId = (dt_th_matrix.First().tophat_customer_detail_Id.Equals c.Customer_No)
But that is not it (obviously)
var mainPull = (from c in cDb.DistributionStopInformations
join rh in cDb.DistributionRouteHeaders on c.Route_Code equals rh.Route_Code
where c.Company_No == 1 &&
(accountNumbers.Contains(c.Customer_No)) &&
(brancheSearchList.Contains(c.Branch_Id) && brancheSearchList.Contains(rh.Branch_Id)) &&
c.Shipment_Type == "D" &&
(c.Datetime_Created > dateToSearch || c.Datetime_Updated > dateToSearch) &&
rh.Company_No == 1 &&
((rh.Route_Date == routeDateToSearch && c.Route_Date == routeDateToSearch) ||
(rh.Route_Date == routeDateToSearch.AddDays(1) && c.Route_Date == routeDateToSearch.AddDays(1)))
orderby c.Unique_Id_No
select new
{
c.Datetime_Updated,
th_customerId = ("Query goes here somehow")
c.Datetime_Created,
c.Unique_Id_No,
c.Original_Unique_Id_No,
c.Unique_Id_Of_New_Stop,
c.Branch_Id,
c.Route_Date,
c.Route_Code,
c.Sequence_Code,
c.Customer_No,
c.Customer_Reference,
c.Shipment_Type,
c.Stop_Name,
c.Stop_Address,
c.Stop_City,
c.Stop_State,
c.Stop_Zip_Postal_Code,
c.Stop_Phone_No,
c.Stop_Arrival_Time,
c.Stop_Departure_Time,
c.Address_Point,
c.Stop_Special_Instruction1,
c.Stop_Special_Instruction2,
c.Stop_Expected_Pieces,
c.Stop_Expected_Weight,
c.Stop_Signature,
c.Actual_Arrival_Time,
c.Actual_Depart_Time,
c.Actual_Service_Date,
c.Stop_Actual_Pieces,
c.Stop_Exception_Code,
c.Created_By,
rh_Route_Date = rh.Route_Date,
routeHeaderRouteCode = rh.Route_Code,
rh.Actual_Driver,
rh.Assigned_Driver,
rh_routeDate = rh.Route_Date
}).ToArray();
I will try and clarify the above.
What I need is for the Linq query to say :
For each record that I pull I will goto the Array named dt_th_matrix and get the record that matches for this line and use it.
The data in the matrix looks exactly like this:
Record 1: datatrac_customer_no: 227, tophat_customer_detail_Id 1
Record 2: datatrac_customer_no: 228, tophat_customer_detail_Id: 1
Record 3: datatrac_customer_no: 910, tophat_customer_detail_Id: 5
Then for the first record pulled in the mainPull the field c.customer_no == 228 so I need the query in the select new statement to replace th_customerId with 1 (from Record 2 in the Matrix.
Then say the next record pulled in the mainPull the field c.customer_no = 910 the th_customerId would be 5.
That is what the first line of my foreach statement is currently doing. I want to move that logic to inside my LINQ query.
If I understand you correctly, using a dictionary with a key of datatrac_customer_no and a value of tophat_customer_detail_Id would be a good idea here:
var dt_th_matrix = (from m in aDb.Matrix_Datatrac_TopHat select m).ToDictionary(m=>m.datatrac_customer_no,m=>m.tophat_customer_detail_Id);
With this you should be able to replace your "Query goes here somehow" with
dt_th_matrix[c.Customer_No]
Using LINQ would be possible as well, but I don't think it's worth the performance overhead and reduction in readibility.
If you still want to use LINQ for this with your original matrix, this should work as your query:
dt_th_matrix.Single(m => m.datatrac_customer_no == c.Customer_No).tophat_customer_detail_Id
Both expressions will throw an exception if the key is not found or exists multiple times - but if I understand your structure correctly this should not be possible. Otherwise you need to check for this.

LINQ does not recognize joined table in select clause

I am left joining expected records to a returned set and attempting to determine if the expected column was updated correctly. The Column to be updated is determined by a string in the expected row.
Problem: I have a compile error I don't understand.
Cannot resolve symbol dbRow
(where bold/ bracketed by ** in QtyUpdated field).
var x = from addRow in expected.AsEnumerable()
join dbRow in dtDB.AsEnumerable()
on
new { key1= addRow[0], key2=addRow[1] ,key3=addRow[3] }
equals
new { key1=dbRow["TransactionID"],
key2=dbRow["TransactionItemID"],
key3=dbRow["DeliverDate"]
}
into result
from r in result.DefaultIfEmpty()
select new {TID = addRow[0], ItemID = addRow[1], DeliveryDate= addRow[3],
QtyUpdated= (
addRow[6].ToString() == "Estimated" ? **dbRow**["EstimatedQuantity"] == (decimal)addRow[5] :
addRow[6].ToString() == "Scheduled" ? **dbRow**["ScheduledQuantity"]==(decimal)addRow[5] :
addRow[6].ToString() == "Actual" ? **dbRow**["ActualQuantity"]== (decimal)addRow[5] : false)
};
I know this seems wonky, its a tool for Q/A to test that the Add function in our API actually worked.
Yes, dbRow is only in scope within the equals part of the join. However, you're not using your r range variable - which contains the matched rows for the current addRow... or null.
Just change each dbRow in the select to r. But then work out what you want to happen when there aren't any matched rows, so r is null.

NHibernate C# e SQL Server

Good Morning,
I wonder if there's any method within the NHIBERNATE to which I can retrieve the first row of the table?
For example:
Line | ID | Name |Last Name |
1 | 0 | Test | of Information |
2 | 1 | Mauricio | Silva |
If I want the first line or the line 1 of the table
You can use Linq to create queries with nHibernate. There is a method called FirstOrDefault() which takes only the first record. If the query return empty, the FirstOrDefault method will return null, so, remember to check the result before using, for sample:
var firstItem = session.Query<Entity>().FirstOrDefault();
if (firstItem != null)
{
string name = firstItem.Name;
// use object
}
NHibernate does support paging, so we can select "any" record using the .Take() and .Skip(). In our case we can do it like this:
var list = session
.QueryOver<Person>()
.Take(1) // this will take just a first record
//.Skip(0) // we can even skip some, to get next page
;
Then the resulting list will contain 1 or none row...
var person = list.FirstOrDefault();
Also, we can never be sure, what order will be used by DB engine, so we should use explicit ORDER BY:
var list = session
.QueryOver<Contact>()
.OrderBy(p => p.ID)
.Asc
.Take(1)
;
Now we can be sure, that the first result will be with ID == 0

Linq to Entities Querying for Nullable data types

I got a scenario where we are doing soft delete on the rows in database. I want to include the rows that are not deleted. How can I achieve it using LINQ.
Say
from c in context.ASDSet
where (c => c.DeletedFlag.HasValue && !c.DeletedFlag.Value)
But I couldn't achieve the result.
I want the resultant SQL to be of form:
select * from table where IsNull(column, 0) = 0
It sounds like you actually want:
var query = Context.ASDSet.Where(c => c.DeletedFlag == null ||
c.DeletedFlag.Value == false);
In other words, that includes rows where the flag is null, whereas your current query excludes rows where the flag is null.

Categories

Resources