Must declare the scalar variable - Why isn't my parameter recognized? - vb.net

I'm using Entity Framework to send a query to the database using ExecuteStoreQuery
If (DBEntity.ExecuteStoreQuery(Of Integer)("SELECT COUNT(ReceiptUID) FROM qryRptSrc_Cust_GoodsReceipt_Issues WHERE ReceiptUID = #Recpt", ReceiptUID)(0) > 0) Then ....
Which gives me the error message that my scalar variable #Recpt hasn't been declared. I know what that error message means, but I'm wondering why it's being thrown in this case. ReceiptUID is a Guid with the correct value. The parameters that are passed don't have to be DbParameter objects, they can just be values and it should work fine. I've done it that was in the past before without issue, and even MSDN states
The parameters value can be an array of DbParameter objects or an array of parameter values. If only values are supplied, an array of DbParameter objects are created based on the order of the values in the array.
I could create a DbParameter object instead, but I'd like to know why this case isn't working.

Token answer:
Try #p0 instead of #Recpt

Related

What is the purpose of the name argument in ADODB CreateParameter method?

So I am working on modifying an existing query in classic ASP. Classic ASP is fairly new to me, especially this ADODB Command stuff.
As it says on Microsoft's Docs
Name
Optional. A String value that contains the name of the Parameter object.
While the other stuff is also nothing I'm familiar with, those are questions for another day.
sql = "INSERT INTO Paintings (pieceName, artistName, description, galleryID) VALUES (?, ?, ?, ?)"
set sqlCmd = Server.CreateObjects("ADODB.Command")
sqlCmd.Parameters.Append(sqlCmd.CreateParameter("#PieceName",adVarChar,adParamInput, 256, txtPieceName))
sqlCmd.Parameters.Append(sqlCmd.CreateParameter("#ArtistName",adVarChar,adParamInput, 256, txtArtist))
sqlCmd.Parameters.Append(sqlCmd.CreateParameter("#Description",adVarChar,adParamInput, 5000, txtDescription))
sqlCmd.Parameters.Append(sqlCmd.CreateParameter("#Description",adInteger,adParamInput, 256, txtGalleryID))
ADODBCon.query(sql, sqlCmd)
Point is, the code is from their live branch. I can see that #Description doesn't match the SQL, so I can figure the command is either case insensitive or the name argument isn't related to the SQL at all.
Second, #Description is used twice and still works, with two different types. I know it says optional, but if it does not relate to the SQL, and can exist by the same name with different types, is it just for readability?
I'm sorry if A String value that contains the name of the Parameter object completely explains its purpose and I'm just not getting it, but what is the purpose of the name argument?
The CreateParameter method is actually creating a Parameter object which the .Append method then adds to the ADODB.Command object's, sqlCmd in this case, Parameters collection. Since it is a collection, the name is optional as a collection item can be accessed by item index.
From the documentation on Parameter Name property:
For Parameter objects not yet appended to the Parameters collection, the Name
property is read/write. For appended Parameter objects and all other objects,
the Name property is read-only. Names do not have to be unique within a
collection.

VB.net String Reverse Property different based on Env

I am debugging an application that runs on a server and users will access the application on another server. The application uses encryption and as part of the key, I am using the String.Reverse property.
Dim Mystring As String = "123abc"
Dim reverse = String.Format("{0},{1}", Mystring.Reverse)
The string reverse is different when I run it from one machine (RDP/Citrix Environment ASP.NET 4.6.1). The value is:
System.Linq.Enumerable+<ReverseIterator>d__a2`1[System.Char]
The same string, but ran from another machine (RPD non-Citrix Environment ASP.NET 4.5.2). The value of reverse is:
System.Linq.Enumerable+<ReverseIterator>d__73`1[System.Char]
Why are the values different in the different environments?
Look at this line first:
Dim reverse = String.Format("{0},{1}", Mystring.Reverse)
Specifically, this expression:
Mystring.Reverse
Reverse is a function, not a property, but it's missing the parentheses (). The trick here is the String.Format() method accepts the base Object type as an argument, and compiler is able to treat the MyString.Reverse expression as a delegate type that is convertible to object. The values you see in your output are the result of calling .ToString() on that function delegate. It's the type name for the function, rather than anything to do with the value of your MyString object. Since that type is dynamically and randomly generated at runtime, you'll see different values not only on different platforms, but different runs on the same computer.
In the VB6 era, it was normal to call methods without the parentheses. In the .Net world, always use parentheses when you call a method.
What you want is this:
Dim reverse As String = String.Format("{0},{1}", Mystring.Reverse())
Even here, you're missing the second argument to match the format string. I doubt you'll get the result you expect.
Finally, reversing a string as the key seems very wrong when it comes to encryption. You are using a real cyrptogrpahic algorithm from the System.Security.Cryptography library, right? Right!?
You are not outputting the value of the reversed String but the name of the type used to perform the reversal. That type is dynamically created and randomly named. The "d" in those two names means "dynamic" and the "a2" and "73" parts are random.
Basically, what you perceive to be an issue is not an issue. The problem is that you're not actually creating a String from the reversed output. You say "String.Reverse property but that is NOT a property. It is a method and it is not a member of the String class but rather an extension method on the IEnumerable(Of T) interface. You are treating your String as an enumerable list of Char values and reversing that. If you want a String from that then you need to create one, i.e.
MyReversedString = New String(Mystring.Reverse().ToArray())
That will push the contents of your iterator into an array and then create a new String object from that array.

Setting a variable to null value in inline if statement

I'm trying to use the following code to check for a DBNull and set the variable to nothing if it is, or a short if it isn't. The problem is it is failing to set the variable to Nothing and sets it to a 0 instead. Anybody know why?
variable = If(currentRow.Item("variable") Is DBNull.Value,
Nothing, CShort(currentRow.Item("variable")))
If variable is declared As Short? then the code works with a slight tweak: you need to cast either operand of If to the target type first:
variable = If(condition, CType(Nothing, Short?), CShort(…))
(You could also have cast the third operand instead, or both.)
This cast is necessary because of how If deduces types: if the two result types mismatch, a common type is deduced which is the closest parent type, i.e. a type from which both inherit. However, with Nothing, new rules come into play because as far as VB is concerned, Nothing is already a valid Short – a default-initialised one (see old answer below for explanation). So VB doesn’t try any type coercion, it simply uses Short as the return value.
Old answer below, assuming that OP had declared variable As Short:
You cannot set value types to Nothing. If you assign Nothing to a value type then it will be set to its type’s default value instead – which is 0 for Short.
You can test this easily:
Dim s as Short = Nothing
Console.WriteLine(s)
Setting a value type to Nothing is the same as invoking its default constructor (New Short()) or declaring a new variable of that type without initialising it. The corresponding operation in C# would be to assign default(T) (short s = default(short)).
If you want to represent null value types, you have to use nullable types:
Dim s as Short? = Nothing
Now s is of type Nullable<Short> (Short? is a shortcut of that) and can be assigned a proper Nothing.

Core Data - Fetch object with optional attribute

I have an EntityA which has an optional attribute int32 result. When I create EntityA I do not set the result attribute. Then later on when I fetch it I expect it to have nil value but for some reason it's set to 3 even though I have not set this attribute.
What's going on here?
1st possible issue:
You have set a default value in the model editor. Select the attribute and check the inspector.
2nd possible issue:
You are retrieving or showing the wrong value. Show the code you are using to find out that result is '3'.
3rd possible issue:
You are setting the value later inadvertently, perhaps in a loop or something similar. Do a text search for the attribute to find a possible occurrence in your code.
Your int32 will be stored wrapped into a NSNumber object. If you don't provide a value, no NSNumber object will be created - sql will treat it as NULL.
The iOS Core Data Programming Guide says:
You can specify that an attribute is optional—that is, it is not
required to have a value. In general, however, you are discouraged
from doing so—especially for numeric values (typically you can get
better results using a mandatory attribute with a default value—in the
model—of 0). The reason for this is that SQL has special comparison
behavior for NULL that is unlike Objective-C's nil. NULL in a database
is not the same as 0, and searches for 0 will not match columns with
NULL.
So, it may be better to either make the attribute mandatory and set it to a distinct value, or to pass in NSNumber from the start.

LINQ to Entities does not recognize the method [Type] GetValue[Type]

I've a simple class like this:
Public Class CalculationParameter{
public Long TariffId{get;set;}
}
In a workflow activity, I've an Assign like this:
(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId).FirstOrDefault()
Dto is passed to Activity as an Input Argument.
It raise following error and I'm wondering how to assign Id. Any Idea?
LINQ to Entities does not recognize the method 'Int64
GetValue[Int64](System.Activities.LocationReference)' method, and this
method cannot be translated into a store expression.
How can I assign the calculationParameter.TariffId to tariffDetial.TariffId?!
UPDATE:
Screen shot attached shows that how I'm trying to assign calculationParameter.TariffId to tariffDetail.TariffId (car.Id = Dto.Id) and the query result should assign to CurrentTrafficDetail object.
Here's your problem. I don't know if there is a solution to it.
As you said in a (now deleted, unfortunately necessitating that I answer) comment, the exception you're getting is
LINQ to Entities does not recognize the method Int64 GetValue[Int64](System.Activities.LocationReference) method, and this method cannot be translated into a store expression.
in your Linq query, calculationParameter is a Variable defined on the workflow. That Variable is actually an instance that extends the type System.Activities.LocationReference and NOT CalculationParameter.
Normally, when the workflow executes, the LocationReference holds all the information it needs to find the value which is assigned to it. That value isn't retrieved until the last possible moment. At runtime, the process of retrieval (getting the executing context, getting the value, converting it to the expected type) is managed by the workflow.
However, when you introduce Linq into the mix, we have the issue you are experiencing. As you may or may not know, your expression gets compiled into the extension method version of the same.
(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId)
.FirstOrDefault()
is compiled to
db.Context.TariffDetails
.Where(x => x.TariffId = calculationParameter.TariffId)
.FirstOrDefault();
When this executes, L2E doesn't actually execute this code. It gets interpreted and converted into a SQL query which is executed against the database.
As the interpreter isn't omniscient, there are a well defined set of limitations on what methods you can use in a L2S query.
Unfortunately for you, getting the current value of a LocationReference is not one of them.
TL:DR You cannot do this.
As for workarounds, the only thing I think you can do is create a series of extension methods on your data context type or add methods to your CalculationParameter class that you can call from within the Expression Editor. You can create your Linq to Entities queries within these methods, as all types will already have been dereferenced by the workflow runtime, which means you won't have to worry about the L2E interpreter choking on LocationReferences.
*Edit: A workaround can be found here (thanks to Slauma who mentioned this in a comment on the question)