LinQ to Sql project with stored procedures - c#

I'm trying to make my first LINQ with asp website so I built a database with one table and I made a stored procedure which selects from this table by the id here it is :
ALTER PROCEDURE select_article_by_id
#artcileid int
AS
select * from articles where artcileid=#artcileid
RETURN
then I dragged and droped it into my DataClasses.dbml
when I run the website this problem appear
An invalid data source is being used for articleDL.
A valid data source must implement either IListSource or IEnumerable.
and gives me this sorce Error :
Line 16: string art_id = Request.QueryString["art_id"];
Line 17: if (art_id != null)
Line 18: articleDL.DataSource = DS.select_article_by_id(int.Parse(art_id)).Single();
Line 19:
Line 20: else

You're setting the data source accordingly:
articleDL.DataSource = DS.select_article_by_id(int.Parse(art_id)).Single();
By using .Single(), you are taking the one and only record returned by select_article_by_id and trying to make that single record the data source. It's telling you that's not allowed.
A list implements IEnumerable, which it's telling you is allowed. A single record does not implement IEnumerable, which it's telling you is not allowed.
Try replacing .Single() with .ToList().

ALTER PROCEDURE select_article_by_id
#artcileid int
AS
BEGIN
SET NOCOUNT ON; --<-- to suppress the message like "(100 row(s) affected)"
select * from articles where artcileid=#artcileid
END
Also you dont need the return key word here.

Related

Entity Framework (Database first) has incorrect return result from stored procedure [duplicate]

This question already has answers here:
Getting data from stored procedure with Entity Framework
(4 answers)
Closed 5 years ago.
Environment:
Visual Studio 2017
SQL Server 2016
EF v6 with a database-first approach
Background: the stored procedure is in the EDMX. My stored procedure sets the return value to 0 if nothing happened, 1 if something affected and value of ##ERROR if errors.
BACKGROUND 1: my stored procedure, LTM_Lease_DeleteSubFiles, does SET NOCOUNT ON at the top and sets return value with RETURN command at the end of the stored procedure.
PROBLEM 1: my call returns -1 which is not even in the stored procedure:
var spResults = context.LTM_Lease_DeleteSubFiles(...)
BACKGROUND 2: my stored procedure DOIOwnerChanges_Apply sets return value with RETURN command at the end of the stored procedure.
PROBLEM 2: my call returns the value of 8 which is not even found in the stored procedure:
var spResults = context.DOIOwnerChanges_Apply(...)
REASON - The template builder for EF (including v6) incorrectly sets the SP up as returning an INT containing the row count rather than the return value because it incorrectly calls the wrong ObjectContext.ExecuteFunction (found in the template-generated class YourDatabaseEntities that is the child of the DBContext).
Why wrong ExecuteFunction? - The result set incorrectly says the row count of changed rows rather than the return value or output parameters because it calls a different ExecuteFunction that discards the results.
The flyover intellisense hint of the ObjectContext.ExecuteFunction says "Executes a stored procedure ….; discards any results returned from the function; and returns the number of rows affected by the execution" rather than the usual "Executes a stored procedure …. with the specified parameters".
WHY PROBLEM 1 IS -1: I believe the SET NOCOUNT ON is causing the SP to return no count result and that Microsoft's ExecuteFunction returns that as error code.
WHY PROBLEM 2 IS 8: The SP returned 8 rows of data rather than the return value because Microsoft used the wrong ExecuteFunction.
SP FIX TO PROBLEM 1 - You have to comment out SET NOCOUNT ON .
SP FIX TO PROBLEM 1 and 2 - You have to change stored procedure to do the SELECT command as last statement instead of the RETURN command.
SOLUTION FIX - 1) After fixing SP, delete SP from Function Imports folder and the Data Store's SP folder. [This change causes EF template generator to make the SP call become an ObjectResult of nullable INT rather than a single INT result.] 2) Reload the SP into the EDMX by using the "Update Model from Database" 3) Rebuild all of your data project where the EDMX resides. 4) Exit Visual Studio and return. 5) Rebuild overall solution.
OTHER WORKAROUNDS - Source: David Browne of Microsoft - 1) Rewrite the SP creating an OUTPUT parameter and return the result there. 2) Do a THROW or RAISERROR when an error is hit.

AS400 Call a stored procedure from another stored procedure

I am trying to call a stored procedure from another stored procedure.
I tried different syntax but with no success.
The first stored procedure returns a table. For the test, I just want to return from the second stored procedure what I got from the first one.
First stored procedure (SP01):
BEGIN
DECLARE C2 CURSOR WITH RETURN FOR
SELECT DISTINCT TBL.*
FROM LIB.TABLE1 TBL;
OPEN C2 ;
END
It works fine when calling it from c#.
Second stored procedure (SP02):
BEGIN
DECLARE C2 CURSOR WITH RETURN FOR
CALL SP01();
OPEN C2 ;
END
I am getting an error:
Vendor Code: -104
Message: [SQL0104] Token SP01 was not valid. Valid tokens: ;. Cause ....
A syntax error was detected at token SP01.
What is the correct syntax / approach for SP02?
EDITED:
In ms access, I was able to create a query QUERY2 based on another query QUERY1:
SELECT * FROM QUERY1;
or even joining it like a table
SELECT * FROM TABLE1 INNER JOIN QUERY1 ON (TABLE1.FIELD1 = QUERY1.FIELD1);
I need to move all my tables and queries from mdb to AS400 and write a C# application that use those queries.
I do not see so much examples on the net, maybe my approach is wrong.
I have multiple queries to run and each one depends on another one. I thought calling one stored procedure from my C# application and this one will call to another one and so on.
Is it a correct way to run a series of queries that depends one to each other?
Or is there a way to call from my c# application to all the queries independently and from the code to build the dependency between them, look like this approach is wrong?
If you are using IBM i version 6.1 or earlier, you cannot access result sets returned by a stored procedure using a language SQL stored procedure. For version 7.1 or later, you can use the ASSOCIATE RESULT SET LOCATORS statement to retrieve the result sets. See the ASSOCIATE LOCATORS statement in the SQL Reference manual (http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/db2/rbafzassocloc.htm?lang=en) for more information.
Once you have the locator, you use the ALLOCATE CURSOR statement (http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_72/db2/rbafzalloccsr.htm?lang=en) to get a cursor from the RESULT SET LOCATOR.
Further examples can be found here: http://www.itjungle.com/fhg/fhg082510-printer02.html

Stored Procedure Return Type Can Not Be Detected

I am trying to drag this procedure over to the dbml in VS 2012 and I am getting the return type cannot be detected message.
I have tried these:
LINQ to SQL - Stored Procedure Return Type Error
The return types for the following stored procedures could not be detected
I tried re-writing the procedure as a CTE and also as union to remove the OR, but it is giving me the same message.
The only return type in the designer properties for the method is int32.
Here is my procedure:
ALTER PROCEDURE [dbo].[GetStringFromFiles]
#SearchWord NVARCHAR(100) = null
AS
BEGIN
SET NOCOUNT ON
SET #SearchWord = UPPER(#SearchWord);
Select
a.FileId <---Guid
, a.FileData <---Binary
, a.BaselineId <---Guid
, a.FileName <---NVARCHAR
, a.FileExtension <---NVARCHAR
, b.FileByItemId <----Guid
, b.ItemId <---Guid
From FileTable a
Inner Join
FileByItem b on a.FileId = b.FileId
WHERE CONTAINS(a.FileData,'FORMSOF(INFLECTIONAL, #SearchWord)') or FREETEXT(a.FileData, #SearchWord)
RETURN 1
END
UPDATE:
A. I can add it if I comment out the entire Where Clause -- Auto-Generated-ReturnType
B. If I take away the or and just use:
WHERE CONTAINS(a.FileData,'FORMSOF(INFLECTIONAL, #SearchWord)')
it lets me add it -- Auto-Generated-ReturnType
C. If I just use
WHERE FREETEXT(a.FileData, #SearchWord)
It throws the error so it doesnt like the FREETEXT
If I comment the where clause out and add it and let it generate the return type then alter the procedure in the db are there any issues with that?
This is somewhat related. I stumbled across the same error today but for a different reason. If your query uses a temporary table in its results then it is unable to automatically assign the return type.
I changed it to a table variable (performance was not a major concern/and was not impacted)
Hope this helps someone browsing.
The line
RETURN 1
is the culprit in both the cases. Lose it and Linq should be able to detect the types your result set.
Linq to Sql won't get the results directly from a Stored procedure.
Instead an ISingleResult will be returned. You have to enumerate
through the result set to get the values returned from the stored
procedure
If the stored procedure have any error also then this error can occur, for me its happened once since one of the table name was changed.
Another factor is to set Primary Keys and table relations if possible
A simple way to solve this issue is (December 2019)
Just making double # precede #tmp => ##tmp
Comment out DROP TABLE #tmp => --DROP TABLE #tmp
Execute stored procedure
Drag stored procedure again and That's it, It will generate return type
Last, Turn your store back to the first situation and then save.
Hope I can help.

SELECT ## IDENTITY using SQL Server CE from C# code

Im using Data Adapter/Set in SQL CE, i do create the following query to insert into table and then SELECT ##IDENTITY,
I want this SELECT statement return me the Student ID each time after Inserting into table, here is my Query:
INSERT INTO [Student] ([Name], [Family], [Address], [Phonenumber])
VALUES(#Name,#Family,#Address,#Phonenumber);
SELECT ##IDENTITY;
here is how i call query:
int x = da.Insert("Albert", "Alexandra", "No4.Oxford", Telnum);
Int x suppose to return me ID...
Here is the Error im getting :
There was an error parsing the query. [ Token line number = 4,Token line offset = 1,Token in error = SELECT ]
Insert Query it self it works but once adding SELECT ## IDENTITY at the end im getting error.
I really don't know what i'm doing wrong.
The return value of ExecuteNonQuery will be number of rows effected by these query. so you need to use store procedure instead of Single Query.
According to MSDN, CE doesn't support multiple commands per execution and you need to do this as two commands synchronously.
If you'd like to do this in a single call, you need to use a stored procedure rather than Insert, because it uses ExecuteNonQuery, which does not return any records. Otherwise you'll need to perform a select in another call to determine the identity.
The return value of ExecuteNonQuery is an integer that denotes the number of rows affected by your call.

Inserting Row and getting Id, get error

I insert a value / new row and I need the ID, but I get an error...
SQL code:
INSERT INTO [StoneTable] ([StoneName]) VALUES (#StoneName)
SELECT SCOPE_IDENTITY()
Using this code to insert row and getting the ID:
stoneTableTableAdapter = new StoneTableTabelleTableAdapter();
int id = Convert.ToInt32(stoneTableTableAdapter.InsertStoneNameAndReturnId("anything"));
//And on this 2nd Line I got an error
Error message:
There was an error parsing the query. [ Token line number = 2,Token line offset = 1,Token in error = SELECT ]
What's the problem? In my other project I use the same syntax, with no problems. Tried with ##IDENTITY, as well not working....
See the answer to this question for a suggestion on how to make your example work:
You should change your INSERT to return that inserted ID to you right away (in an OUTPUT clause)
You can only issue a single statement per batch in SQL Server Compact, and you cannot use Scope_identity, but must use ##IDENTITY (remember to keep the connection open betweeen the two calls)

Categories