insert data using labmda expression - entity-framework

I have a insert sp
create procedure sp_insert_services
#Service_Type nvarchar(50),
#Frequency nvarchar(50),
as
insert INTO tbl_fl_Master_List
(Service_Type,Frequency)
values
(#Service_Type,
#Frequency)
now how i write this through lambda expression,linq to sql and EF?
i tried this but this show error
var insert = insertt.tbl_fl_Master_List();
if(insertt!=null)
{
insertt.tbl_fl_Master_List.Add();
}
insertt.SaveChanges();
Error 8 Non-invocable member 'chart_project.Track_Data.tbl_fl_Master_List' cannot be used like a method.
Error 9 No overload for method 'Add' takes 0 arguments
and also i try this
public static string Insert_master_services(string Service_Type,string Frequency)
{
Data insertt=new Data();
tbl_fl_Master_List t = new tbl_fl_Master_List();
t.Service_Type = Service_Type;
t.Frequency = Frequency;
insertt.SaveChanges();
}

Related

Unable to call a PostgreSQL function using callable statement or prepared statement

I have created a PostgreSQL function which is tested on the backend side and it works as expected. However, when I am trying to call it through the Scala module it says that the function doesn't exist.
Function:
create or replace function testing.compareData(ab integer, b json, tablename varchar) RETURNS void as $$
DECLARE
actualTableName varchar := tablename;
histTableName varchar:= actualTableName ||'_hist';
job_id Integer:=0;
begin --<<<< HERE
set search_path to testing; -- Set the schema name
execute 'SELECT id FROM '||actualTableName||' WHERE id =$1' into job_id using ab;
-- if there is data for id in the table then perform below operations
if job_id is not null then
execute FORMAT('INSERT INTO %I select * from %I where id = $1',histTableName,actualTableName) USING ab;
execute FORMAT('DELETE FROM %I where id = $1',actualTableName) USING ab;
EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
-- if id is not present then create a new record in the actualTable
ELSE
EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
END IF;
END; --<<<< END HERE
$$ LANGUAGE plpgsql;
Callable Statement Way:
def callingStoredProcedure(message: String, id: Integer, resourceType: String): Unit = {
val connectionUrl: String = ReadingConfig.postgreDBDetails().get("url").getOrElse("None")
var conn: Connection = null
var callableStatement: CallableStatement = null
try {
conn = DriverManager.getConnection(connectionUrl)
callableStatement = conn.prepareCall("{ call testing.compareData( ?,?,? ) }")
callableStatement.setString(1, message)
callableStatement.setInt(2, id)
callableStatement.setString(3, resourceType)
callableStatement.execute()
} catch {
case up: Exception =>
throw up
} finally {
conn.close()
}
}
Prepared Statement way:
def callDataCompareAndInsertFunction(message: String, id: Integer, resourceType: String): Unit = {
val connectionUrl: String = ReadingConfig.postgreDBDetails().get("url").getOrElse("None")
var pstmt: PreparedStatement = null
var conn: Connection = null
try {
conn = DriverManager.getConnection(connectionUrl)
pstmt = conn.prepareStatement("select testing.compareData(?,?,?)")
pstmt.setInt(1, id)
pstmt.setString(2, message)
pstmt.setString(3, resourceType)
pstmt.executeQuery()
}
catch {
case e: Exception => throw e
}
finally {
conn.close()
}
}
Here, testing is my schema under which the function is created. When ran using both the ways it throws below error:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: function testing.comparedata(character varying, integer, character varying) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Well your first parameter isn't a string, so calling setString(1, ...) will result in the error you quoted in your question.
Your second parameter is declared as json so you can't directly pass a String value there as well. The following should work (given the function definition):
pstmt = conn.prepareStatement("select testing.compareData(?,cast(? as json),?)")
pstmt.setInt(1, id)
pstmt.setString(2, message)
pstmt.setString(3, resourceType)
You might also need to use pstmt.execute() instead of executeQuery() as your function doesn't return anything.

How to use Store procedure in entity frame work

I have created store procedure in Sql server its working.when i imliment it into my entity framework, its throws exception, I am new to this, kindly suggest
//SQL//
create procedure sp_getUserID
#deviceID int,
#userID int out
as
Begin
Select #userID= userId from UserTable
where deviceID = #deviceID
End
// C#
var UserID =0;
// This line error ERROR: //The specified parameter name '#userID' is not valid.
System.Data.Entity.Core.Objects.ObjectParameter UserOutput = new System.Data.Entity.Core.Objects.ObjectParameter("#userID", typeof(int));
var objStoredProcd = dbContext.sp_getUserID(UserOutput, UserLogin.DeviceUUID);
UserID = Convert.ToInt32(UserOutput.Value);

function does not exist in pg_proc in postgresql

I tried to call my user defined function in pgresql from C# code,
my function creation script is as follows,
CREATE OR REPLACE FUNCTION public."GetUserDailyData"(
cid integer,
hid integer,
currday integer)
RETURNS character varying AS
$BODY$
DECLARE
returndata varchar = '';
BEGIN
SELECT data->20+currday into returndata FROM pops
WHERE hybid = hid and cropid = cid;
return returndata;
END
$BODY$
LANGUAGE plpgsql
COST 100;
My method to call this function is as follows,
public static object ExecuteScalar(string conString, string spName, NpgsqlParameter[] param)
{
using (var conn = new NpgsqlConnection(conString))
{
conn.Open();
using (var tran = conn.BeginTransaction())
using (var command = conn.CreateCommand())
{
command.CommandText = spName;
command.CommandType = CommandType.StoredProcedure;
for (var i = 0; i < param.Length; i++)
{
command.Parameters.Add(new NpgsqlParameter());
command.Parameters[i] = param[i];
}
var result = command.ExecuteScalar();
return result;
}
}
}
I tried everything even checked the existence of this function in pg_proc using
select * from pg_proc where proname = 'GetUserDailyData'
and it reflected the function details row.
But every time it is giving the same error.
Any kind of suggestion would be highly appreciated. Thanks.
Adding objects with case sensitive names in PostgreSQL can lead to these complications; in this case you need to specify the name of the stored procedure between quotes, however it would be advisable to simply not create any objects that rely on case sensitivity, use underscores instead, or when create/refer to objects using CamelCase without the quotes (which creates/refers to the objects in low-caps). In any case, you may also need to specify the whole interface (not just the name) as the CommandText, and specify the data types of the parameters (see this).
...
command.CommandText = "\"" + spName + "\"";
...

EntityFrameWork and TableValued Parameter

I'm trying to call a stored procedure from EntityFramework which uses Table-value parameter.
But when I try to do function import I keep getting a warning message saying -
The function 'InsertPerson' has a parameter 'InsertPerson_TVP' at
parameter index 0 that has a data type 'table type' which is currently
not supported for the target .NET Framework version. The function was
excluded.
I did a initial search here and found few posts which says It's possible in EntityFrameWork with some work arounds and few saying it's not supported in current versions.
Does any one know a better approach or solution for this problem?
I ended up doing this, Please note we are working on EF DataContext(not ObjectContext)
Executing a Stored procedure with output parameter
using (DataContext context = new DataContext())
{
////Create table value parameter
DataTable dt = new DataTable();
dt.Columns.Add("Displayname");
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
dt.Columns.Add("TimeStamp");
DataRow dr = dt.NewRow();
dr["Displayname"] = "DisplayName";
dr["FirstName"] = "FirstName";
dr["LastName"] ="LastName";
dr["TimeStamp"] = "TimeStamp";
dt.Rows.Add(dr);
////Use DbType.Structured for TVP
var userdetails = new SqlParameter("UserDetails", SqlDbType.Structured);
userdetails.Value = dt;
userdetails.TypeName = "UserType";
////Parameter for SP output
var result = new SqlParameter("ResultList", SqlDbType.NVarChar, 4000);
result.Direction = ParameterDirection.Output;
context.Database.ExecuteSqlCommand("EXEC UserImport #UserDetails, #ResultList OUTPUT", userdetails, result);
return result == null ? string.Empty : result.Value.ToString();
}
My Table-Value-Parameter (UDT Table) script looks like this:
CREATE TYPE [dbo].[UserType] AS TABLE (
[DisplayName] NVARCHAR (256) NULL,
[FirstName] NVARCHAR (256) NULL,
[LastName] NVARCHAR (256) NULL,
[TimeStamp] DATETIME NULL
)
And my store procedure begins like
CREATE PROCEDURE UserImport
-- Add the parameters for the stored procedure here
#UserDetails UserType Readonly,
#ResultList NVARCHAR(MAX) output
AS
For Stored procedure without output parameter we don't need any ouput parameter added/passed to SP.
Hope it helps some one.
Perhaps we could also consider the SqlQuery method:
[Invoke]
public SomeResultType GetResult(List<int> someIdList)
{
var idTbl = new DataTable();
idTbl.Columns.Add("Some_ID");
someIdList.ForEach(id => idTbl.Rows.Add(id));
var idParam = new SqlParamter("SomeParamName", SqlDbType.Structured);
idParam.TypeName = "SomeTBVType";
idParam.Value = idTbl;
// Return type will be IEnumerable<T>
var result = DbContext.Database.SqlQuery<SomeResultType>("EXEC SomeSPName, #SomeParamName", idParam);
// We can enumerate the result...
var enu = result.GetEnumerator();
if (!enu.MoveNext()) return null;
return enu.Current;
}
var detailTbl = new DataTable();
detailTbl.Columns.Add("DetailID");
detailTbl.Columns.Add("Qty");
txnDetails.ForEach(detail => detailTbl.Rows.Add(detail.DetailID, detail.Qty));
var userIdParam = new System.Data.SqlClient.SqlParameter("#UserID", SqlDbType.Int);
userIdParam.Value = 1;
var detailParam = new System.Data.SqlClient.SqlParameter("#Details", SqlDbType.Structured);
detailParam.TypeName = "DetailUpdate";
detailParam.Value = detailTbl;
var txnTypeParam = new System.Data.SqlClient.SqlParameter("#TransactionType", SqlDbType.VarChar);
txnTypeParam.Value = txnType;
var result = await db.Database.ExecuteSqlCommandAsync("MySP #UserID, #Details, #TransactionType", userIdParam, detailParam, txnTypeParam);
if(result >= 0)
return StatusCode(HttpStatusCode.OK);
else
return StatusCode(HttpStatusCode.InternalServerError);

Postgres function(via npgsql) call to ExecuteNonQuery returns -1 as result for rows affected

I have a simple function that just inserts the parameter values provided to it into columns in a table.
When I run the function via the ExecuteNonQuery() method on the command object I always get -1, even if the insert took place.
If i run the same query as a Text command it gives be the correct result of 1.
I'm new to postgresql/npgsql. Is there trick to making the function feed back the number of rows affected? Something like "set nocount off" in SQL Server?
EDIT:
The code I am using: (with npgsql 2.0.11)
var connStr = #"Server=127.0.0.1;Port=5432;User Id=postgres;Password=***;Database=Test;";
using (var conn = new NpgsqlConnection(connStr)) {
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "insert_something";
cmd.CommandType = CommandType.StoredProcedure;
NpgsqlCommandBuilder.DeriveParameters(cmd);
cmd.Parameters["_id"].Value = 1;
cmd.Parameters["_val"].Value = 2;
var rowsAffected = cmd.ExecuteNonQuery();
Console.WriteLine(rowsAffected);
}
}
I haven't used Npgsql, but the documentation has an example with
the following code:
NpgsqlCommand command = new NpgsqlCommand("insert into table1 values(1, 1)", conn);
Int32 rowsaffected;
try
{
rowsaffected = command.ExecuteNonQuery();
}
If you are talking about some PostgreSQL function like this:
CREATE FUNCTION myinsert(integer) RETURNS void
LANGUAGE 'sql' AS 'INSERT INTO mytable VALUES ($1)';
and you are doing something like SELECT myinsert(1);, you can't get the number of affected rows, because you are running a SELECT and what the function does internally is opaque to you.
For ExecuteNonQuery() to get the number of rows affected, your postgresql function should return just that. An example would be:
CREATE OR REPLACE FUNCTION insert_something(_id int, _val int)
RETURNS int as $$
DECLARE count int;
BEGIN
INSERT INTO some_table (id, value) VALUES(_id, _val);
GET DIAGNOSTICS count = ROW_COUNT;
RETURN count;
END;
$$ language plpgsql;
Now if you call ExecuteNonQuery() from your code, you should get the inserted rows count.
Here's how I have implemented and its working for me without any issues:
Add an OUT Parameter to your function.
CREATE OR REPLACE FUNCTION schema.UpdateSomeValue(
IN par_updateId text,
OUT par_returnvalue INT4)
BEGIN
UPDATE schema.TableToUpdate
SET status = 1
WHERE ID = par_updateId;
GET DIAGNOSTICS par_returnvalue = ROW_COUNT;
END;
Now on the C# side
private int UpdateSomeValue()
{
var connStr = #"Server=127.0.0.1;Port=5432;UserId=postgres;Password=***;Database=Test;";
int result = -1;
using (var conn = new NpgsqlConnection(connStr)) {
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "shema.UpdateSomeValue";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("par_updateId",NpgsqlTypes.NpgsqlDbType.INT, 1);
NpgsqlParameter outParm = new NpgsqlParameter("par_returnvalue",
NpgsqlTypes.NpgsqlDbType.Integer)
{
Direction = ParameterDirection.Output
};
cmd.ExecuteNonQuery();
result = Convert.ToInt32(outParm.Value);
}
}
return result;
}
PS : I tried the just ExecuteNonQuery() approach but it was always returning -1 for me (as if no rows has been affected NpgsqlDocumentation) Using above way I was able to capture the Number of rows affected from the PostgreSQL function and with OUT parameter it was easy to catch the affected rows on the client side.