Entity Framework error when import scalar function - c#

I have an application with C#, I use entity framework to connect at database T-SQL. So I want to call a scalar function.
When I try to import this function I have a warning message:
Avviso 1 Error 6046: Unable to generate function import return type of
the store function 'F_GetCodiceAppezzamento'. The store function will
be ignored and the function import will not be
generated. C:\Users\michele.castriotta\Source\Workspaces\OmniaFarm\ws\WSOmniaFarm\WSOmniaFarm\FarmGEO_ToolEntities.edmx 1 1 WSOmniaFarm
So I have insert this method into FarmGeoo_ToolEntities class:
[DbFunction("FarmGEO_ToolEntities.Store", "F_GetCodiceAppezzamento")]
public string F_GetCodiceAppezzamento(string partitaIva)
{
var lObjectContext = ((IObjectContextAdapter)this).ObjectContext;
return lObjectContext.
CreateQuery<string>(
"FarmGEO_ToolEntities.F_GetCodiceAppezzamento",
new ObjectParameter("PIVAImpresa", partitaIva)).
Execute(MergeOption.NoTracking).
FirstOrDefault();
}
But when I try to call this method I have error:
'F_GetCodiceAppezzamento' non definito nel contenitore di entità
'FarmGEO_ToolEntities'. Vicino identificatore semplice, riga 1,
colonna 34."}

Related

Reading single BLOB entry from stored procedure

I need to complete my task using only stored procedures.
In my app I have Models called 'Document' and 'DocumentInfo' which refers to mysql tables. For example I got simplest stored procedure to get list of documentInfos by Filename:
SQL:
CREATE PROCEDURE `GetDocumentByName` (DocName varchar(255))
BEGIN
Select * from GetAllDocuments where DocumentName like DocName;
END$$
C#:
public List<DocumentsInfo> GetDocumentByName(string Filename)
{
return db.DocumentsInfo.FromSql("CALL GetDocumentByName({0})", Filename).ToList();
}
As you can see I use db - this is dbContext. DocumentsInfo it's my model and I returned a list of DocumentsInfo objects. But what if I don't need to return whole object, but only one column?
Now I need to do the same but with 'Document' but only this time I need to take only one field - DocumentBody, which is BLOB
SQL:
CREATE PROCEDURE `GetDocumentBodyById` (DocumentBodyID INT(11))
BEGIN
Select DocumentBody from Document where idDocumentBody = DocumentBodyID;
END$$
C#:
var test = db.FromSql("CALL GetDocumentBodyById({0})", DocumentID).FirstOrDefault();
Gives me an error:
'DBContext' does not contain a definition for 'FromSql' and no
accessible extension method 'FromSql' accepting a first argument of
type 'DBContext' could be found (are you missing a using directive or
an assembly reference?)
Also tried to use this option:
var test = db.Database.SqlQuery<object>("CALL GetDocumentBodyById({0})", DocumentID).FirstOrDefault();
But received new error:
'DatabaseFacade' does not contain a definition for 'SqlQuery' and no
accessible extension method 'SqlQuery'
How to call stored procedure which should return only one value, not whole model object? Is it possible with .net core?
For FromSql, it is used with Query, you could define a new model for return result.
public class ResultDto
{
public string Name { get; set; }
}
Define Query in OnModelCreating
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Query<ResultDto>();
}
Useage:
var result = _context.Query<ResultDto>().FromSql("exec GetDocumentBodyById {0}", 1).ToList();

How to use existing stored procedure & functions with Entity Framework Code-first

I'm using EntityFramework.Functions library that is used to call a stored procedure or a function when we use Entity Framework code-first.
I have a stored procedure that returns a nullable long value. But I get an error:
System.Nullable`1[[System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] for method AddRecord_SP is not supported in conceptual model as a structural type.
The functions is declared in my DataContext class:
[Function(FunctionType.StoredProcedure, "Sp_name", Schema = "acnt")]
public virtual ObjectResult<Nullable<long>> AddRecord_SP(string i_Params)
{
var i_ParamsParameter = i_Params != null ?
new ObjectParameter("I_Params", i_Params) :
new ObjectParameter("I_Params", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Nullable<long>>("Sp_name", i_ParamsParameter);
}
As far as I know Stored procedures can't actually specify that parameters are non-nullable.
May be you can try to specify the return parameters.
[return: Parameter(DbType = "")]
Below is Sample Code from My project you can refer.
[Function(FunctionType.StoredProcedure, "GetTop100", Schema = "biz")]
public IQueryable<GetTop100Emp> GetTop100EmpList(long? FKTenant, int IsFilter)
{
var parameters = new ObjectParameter[] {
new ObjectParameter("FKTenant", FKTenant),
new ObjectParameter("IsFilter", IsFilter),
};
return this.ObjectContext.ExecuteFunction<GetTop100Emp>("GetTop100", parameters).AsQueryable<GetTop100Emp>();

How to assign ObjectResult<> from EF

After using DB first approach with EF my context.cs file has the follwing for a stored procedure:
public virtual ObjectResult<selectCases_Result> selectCases()
{
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<selectCases_Result>("selectPurgeCaseFolio");
}
In a sepearte class file I'm trying to invoke it to get the result with the following:
public SelectCases()
{
var result = _context.selectCases;
}
However the error I get is on result:
"Cannot assign method group to an implicitly-typed local variable"
How can I get the result of this select query into a dataset or anyother type of object to see the results?
You forgot to call the method (with ())
var result = _context.selectCases();
You are trying to call it like a property when you should be calling it as a method

Stored Procedure List Run Time Conversion

Inside My 'MyOtherViewModel' I have the below code that is
Throwing Error: Argument Type myStoredProcedure not Assignable to parameter type MyDbTable
It is throwing # (this, c) Compile Time Error
var query = myWCFClient.myStoredProcedure();
//Some Other Stuff
query.ToList().ForEach(c => myCollection.Add(new MyViewModel(this, c)));
Inside MyViewModel I have :
public MyViewModel(MyOtherViewModel owner, MyDbTable table)
:base(owner, "String")
{
//other stuff
}
Then I try
var t = ((IEnumerable)query).Cast<MyDbTable>().ToList();
t.ToList().ForEach(c => mCollection.Add(new MyViewModel(this, c)));
And Get: Unable to cast object of type 'myStoredProcedure' to type 'MyDbTable'. Run Time Error
What is the best way to handle this in VS 2012, c# .Net 4.5 using WCF.
Procedure is myStoredProcedure[] and this is returning a count of 0
var t = query.OfType<MyDbTable>().ToList();
In your first piece of code you are putting objects of type myStoredProcedure in the constructor of MyViewModel while that constructor expects an object of type MyDbTable. That's why you get a compile time error on that piece of code.
The second piece of code you try to cast the myStoredProcedure to a MyDbTable. That's why you get a run time exception on that piece of code.
Your WCF-service is returning other objects than you expect. Investigate the service or change the constructor of MyViewModel to accept objects of class myStoredProcedure.

Calling Scalar User Defined Function in Where Condition in Entity Framework

I have a SQL Function 'DecryptField' as :
ALTER FUNCTION [dbo].[DecryptField]
(
#EField as varchar(10)
)
RETURNS varchar(10)
BEGIN
Declare #decrypted varchar(10)
SET #decrypted = 'Something' + #EField
return #decrypted
END
I want to call that function in Entity Framework.(EF Version : 6.0 target framework: 4.0).
By searching over the Internet, I found a solution to create a class like :
public static class UDFFunctions
{
[EdmFunction("MyModel.Store", "DecryptField")]
public static string DecryptField(string field)
{
// This code will never been run against real SQL database
// This will help any test requires this method pass
throw new NotSupportedException("Direct calls not supported");
}
}
And then use this function as :
User user = null;
var query = from u in _context.Users.AsNoTracking()
where u.Login == userName && UDFFunctions.DecryptField(u.Password) == password
select u;
user = query.SingleOrDefault();
return user;
I am getting an error at runtime : LINQ to Entities does not recognize the method 'System.String DecryptField(System.String)' method, and this method cannot be translated into a store expression.
Please tell me if I am missing anything or doing anything wrong.

Categories