LINQ to SQL doesn't update if I include a calculated column - sql

I am populating a DataGrid with the following LINQ code :
Dim myClients = From p In dc.Persons _
Select p
I can navigate my DataGrid, make changes and then click on a button that calls
dc.SubmitChanges()
All of this works well and updates SQL Server.
I then wanted to add a single additional column that would display a calculated age based on a Function. I used the following code to create a PersonAge column and it worked.
Dim myClients = From p In dc.Persons _
Select New With {p.PersonID, _
p.PersonName, _
p.PersonGender, _
.PersonAge = CalcCurrentAge(p.PersonDOB, p.PersonFirstContactDate, p.PersonFirstContactAge) _
}
However, I noticed that I can no longer successfully save any updates back to SQL.
So my question is, how can I take the simplicity of the first LINQ code which saves updates correctly, and mix it with the second LINQ code which includes the PersonAge column to create an updatable DataGrid with a calculated age column?

Make your calculation for your data column in your DataGrid, rather than in the Linq statement.
http://www.dotnetjohn.com/articles.aspx?articleid=18

Related

Chinese characters in Access SQL Query

After populating the recordsource the next action is clicking on one of the fields populated to "activate" the record. When clicking this, the goal is that the SEC_ID (A GUID, Number Data Type) is stored as a tempvar and used in future queries. This GUID is also placed in a text box just for a visual debug. However it doesn't put the GUID, it puts random Chinese characters. I've tried to place it into a MsgBox just to also see and it spits out "???????".
My code to populate the rowsource:
Dim componentListSQL As String
If FCSUtilities.AssessmentUoM = "Metric" Then
componentListSQL = "SELECT DISTINCT [100b_Working].SEC_SYS_COMP_ID, [100b_Working].SEC_ID, [110b_RO_Material_Category].MAT_CAT_DESC, [110b_RO_Component_Type].COMP_TYPE_DESC, [110b_RO_Material_Category].MAT_CAT_ID, [110b_RO_Component_Type].COMP_TYPE_ID, [100b_Working].ID_Number, [100b_Working].Model, [100b_Working].Serial_Number, [100b_Working].Capacity, [100b_Working].Manufacturer, [100b_Working].SEC_YEAR_BUILT, ROUND([100b_Working].SEC_QTY, 0) AS SEC_QTY, [100b_Working].UOM_MET_UNIT_ABBR, [100b_Working].UOM_ENG_UNIT_ABBR, [100b_Working].Equipment_Make, [100b_Working].UOM_CONV " _
& "FROM (110b_RO_Units_Conversion INNER JOIN (110b_RO_Component_Type INNER JOIN (110b_RO_Material_Category INNER JOIN 110b_RO_CMC ON [110b_RO_Material_Category].MAT_CAT_ID = [110b_RO_CMC].CMC_MCAT_LINK) ON [110b_RO_Component_Type].COMP_TYPE_ID = [110b_RO_CMC].CMC_CTYPE_LINK) ON [110b_RO_Units_Conversion].UOM_ID = [110b_RO_CMC].CMC_UoM) INNER JOIN 100b_Working ON [110b_RO_CMC].CMC_ID = [100b_Working].SEC_CMC_LINK " _
& "WHERE ((([100b_Working].SEC_SYS_COMP_ID) = [Forms]![200a_MainWindow]![txtDebugCompSysID]) And (([100b_Working].SEC_ID) Is Not Null)) " _
& "ORDER BY [110b_RO_Component_Type].COMP_TYPE_DESC;"
Me![210_ComponentList].Form.RecordSource = componentListSQL
End If
The OnClick event:
Private Sub txtMaterialCategory_Click()
Me.txtActiveSecID.Value = Me.txtSecID.Value
End Sub
The txtSecID appears as a GUID as it should but it's in the txtActiveSecID that it becomes Chinese characters even if I attempt to put it as a tempvar then set it into the txtActiveSecID.
I'm not exactly sure what is going on. Looking at different stacks, it points that it's due to long/memo field but as I said previously, the SEC_ID field data type is Number.
Per MS documentation https://learn.microsoft.com/en-us/office/vba/api/Access.Application.StringFromGUID:
The Microsoft Access database engine stores GUIDs as arrays of type Byte. However, Access can't return Byte data from a control on a form or report. To return the value of a GUID from a control, you must convert it to a string. To convert a GUID to a string, use the StringFromGUID function. To convert a string back to a GUID, use the GUIDFromString function.
StringFromGUID(Me.txtSecID.Value)
However that results in output like:
{guid {2786C27B-CB7C-4DEA-8340-1338532742DE}}
That should still work as filter critera but could do further processing to extract GUID from that string. Use string manipulation functions to remove the {guid header and trailing }. Review Access - GUID value stored in textbox, can't be used in SELECT statements

Query Datagridview and output to Datagridview vb.net

I just want to make sure I am reading microsoft's documentation correctly, and that I understand the structure appropriately.
First here is link I am reading:
https://msdn.microsoft.com/en-us/library/bb669099(v=vs.110).aspx
Second here is the code they suggested:
' Create a table from the bound view representing a query of
' available products.
Dim view As DataView = CType(bindingSource1.DataSource, DataView)
Dim productsTable As DataTable = CType(view.Table, DataTable)
' Set RowStateFilter to display the current rows.
view.RowStateFilter = DataViewRowState.CurrentRows
' Query the DataView for red colored products ordered by list price.
Dim productQuery = From rowView As DataRowView In view _
Where rowView.Row.Field(Of String)("Color") = "Red" _
Order By rowView.Row.Field(Of Decimal)("ListPrice") _
Select New With {.Name = rowView.Row.Field(Of String)("Name"), _
.Color = rowView.Row.Field(Of String)("Color"), _
.Price = rowView.Row.Field(Of Decimal)("ListPrice")}
' Bind the query results to another DataGridView.
dataGridView2.DataSource = productQuery.ToList()
Sorry if this seems like a dumb question, but my inquiry is mainly related to understanding how to query it appropriately. The "SELECT" part of this code is at the end, correct? (i.e. Select New With, column_name, column_name etc etc). Sorry to put it in SQL terms but I was wondering if it was more efficient to query a datagridview (kind of using it like a temporary table for a query) than having to either reach back out to DB or loop through contents to check for so and so variable.
And is "bindingSource1" the first datagridview, or the source data (table in db)?

Sorting Data on Form in Access 2010 by VBA

I have the following setup:
Table "Mitarbeiter" (Users) with fields: "UNummer" / "Sortierung" /....
Table "Mo01" (a sheet for every month) with fields: "UNummer" / "01" / "02" / ....
The Field UNummer in Table Mo01 is a combination field that gets Mitarbeiter.UNummer and saves it as text
I call a Form "Monatsblatt" that is based on the table Mo01.
In that Form I have a Field "fldSort" that is calling "Sortierung" from table "Mitarbeiter". The Data in that field is based on "=DomWert("Sortierung";"Mitarbeiter";"UNummer = '" & [ID] & "'")"
This works and looks like this:
I am trying to sort the form by that "fldSort" in Form "Monatsblatt" by using this code:
Form_Monatsblatt.OrderBy = "fldSort"
Form_Monatsblatt.OrderByOn = True
When I start the form with that code running, Access asks for parameters:
I tried a lot of different ways of writing the code, referencing to the field in different ways. I do NOT want to base the form on anything other then the table.
Why not ask the wide world watch "Why Access asking me for Parameter"? That would have brought you to the clue I think. Debug.Print or MsgBox your .OrderBy and you see it's "fldSort", not a valid sort. Access is assuming you want to use a parameter called fldSort, but you want the string in the variable fldSort, but it's not recognized, because of the double quotes surrounding it. Everything between 2 double quotes is interpreted as a string, even it's a var name.
Delete the quotes and everything will work fine (if your sort string is sufficent)!
Form_Monatsblatt.OrderBy = fldSort
[Update]
Late, but now I see the clue. You added a calculated field to the form, but you can't sort or filter them.
Instead of appending this field to the table, create a query and add it there, then you bind the form to the query and add the field to the form. Now you can filter and sort as you like!
The query looks like this:
SELECT *,
Dlookup("Sortierung","Mitarbeiter","UNummer = '" & [ID] & "'") AS ldSort
FROM Mo01;
Or with a join:
SELECT
Mo01.*,
Mitarbeiter.Sortierung AS fldSort
FROM
Mo01
LEFT JOIN
Mitarbeiter
ON
Mo01.ID = Mitarbeiter.UNummer;
Now you can use
Form_Monatsblatt.OrderBy = "fldSort"
Form_Monatsblatt.OrderByOn = True
because you have a bound control called fldSort.
[/Update]

Dynamic variables in linq select statement

I have a listbox that is dynamically filled by certain values depending on what table has been selected from another list box. Once a value is selected, it is being graphed vs a date & time range. With my ignorance of linq: depending on what value is selected, the linq to sql statement I need to create to grab data from my database is different as I can't use an index on an anonymous type.
result = From t In db.APS _
Where t.DateTime >= startDate And _
t.DateTime <= finishDate And t.Weight = weight _
Select t.DateTime, t.TotalConcentration
t.TotalConcentration should be selected if my listbox value is "Total Concentration", but if it's something else, like "Temperature" or "Flow Rate" (connected to appropreate database columns) - this method obviously isn't going to work. I need to be able to dynamically select a specific column from the anonymous type list, or use some other method I'm unaware of to do this. I'm using VB, but if you have a solution in C# it would also be appreciated.
Have a look at Dynamic Linq. Dynamic Linq allows you to specify field and table names in your Linq statements as strings, so you should be able to pass it a string from your listbox to specify the field you want to Select.
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

How to add custom columns to a table that LINQ to SQL can translate to SQL

I have a table that contains procedure codes among other data (let's call it "MyData"). I have another table that contains valid procedure codes, their descriptions, and the dates on which those codes are valid. Every time I want to report on MyData and include the procedure description, I have to do a lookup similar to this:
From m in dc.MyDatas _
Join p in dc.Procedures On m.proc_code Equals p.proc_code _
Where p.start_date <= m.event_date _
And If(p.end_date.HasValue, p.end_date.Value, Now) >= m.event_date _
Select m.proc_code, p.proc_desc
Since there are many places where I want to show the procedure description, this gets messy. I'd like to have the lookup defined in one place, so I tried putting this in an extension of MyData:
Partial Public Class MyData
Public ReadOnly Property ProcedureDescription() As String
Get
Dim dc As New MyDataContext
Return _
(From p in dc.Procedures _
Where p.proc_code = Me.proc_code _
And p.start_date <= Me.event_date _
And If(p.end_date.HasValue, p.end_date.Value, Now) >= Me.event_date _
Select p.proc_desc).SingleOrDefault
End Get
End Property
End Class
Which works when displaying data, but you can't use it in a query, because it doesn't know how to turn it into a SQL statement:
Dim test = _
From x In dc.MyDatas _
Select x.proc_code _
Where x.ProcedureDescription.Contains("test")
Error: The member 'MyProject.MyData.ProcedureDescription' has no supported translation to SQL.
Is there a way to turn a complex lookup (i.e. a non-trivial join) like this into something SQL can recognize so that I can define it in one place and just reference the description as if it were a field in MyData? So far the only thing I can think of is to create a SQL view on MyData that does the linking and bring that into my data context, but I'd like to try to avoid that. Any ideas would be welcomed. Thanks.
You can insert an AsEnumerable() into your query expression. That will convert everything to that point to a result set so that your custom properties can be included in the remainder of the expression (sorry I don't do VB):
var test = _
(from x in dc.MyDatas
(select x.proc_code).AsEnumerable().
Where(x => x.ProcedureDescription.Contains("test"));
this is not an extension method, it's a property
VB.net Extension methods: http://msdn.microsoft.com/en-us/library/bb384936.aspx
Consider using this query as a stored procedure if it's really important.