I'm using a database-first EF6 model with a few scalar-valued functions in it, and I'm having a problem with it not working the way I expected. The SQL function is defined as:
dbo.GetCurrentPayOffAmountFunction(@ApplicationID int, @PayOffDate DateTime)
Returns decimal(18,2)
In the .edmx, I'm using:
<Function Name="GetCurrentPayOffAmountFunction" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" ReturnType="decimal">
<Parameter Name="ApplicationID" Type="int" Mode="In" />
<Parameter Name="PayOffDate" Type="datetime" Mode="In" />
</Function>
In the .cs for the EF project:
[DbFunction("PHXModel.Store", "GetCurrentPayOffAmountFunction")]
public decimal GetCurrentPayOffAmountFunction(int ApplicationID, DateTime PayOffDate)
{
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
var parameters = new List<ObjectParameter>();
parameters.Add(new ObjectParameter("ApplicationID", ApplicationID));
parameters.Add(new ObjectParameter("PayOffDate", PayOffDate));
return Convert.ToDecimal(objectContext.CreateQuery<string>("PHXModel.Store.GetCurrentPayOffAmountFunction(@ApplicationID, @PayOffDate)", parameters.ToArray())
.Execute(MergeOption.NoTracking)
.FirstOrDefault());
}
Now, this all works fine when I call it as part of a select, as so:
decimal app = db.Applications.Take(1).Select (a => db.GetCurrentPayOffAmountFunction(1000, DateTime.Now)).FirstOrDefault();
("Applications" above can be any table in my database, and the function returns the correct value regardless of what I'm actually using to the left of the select).
However, when I try to run the function without a query before it, such as:
decimal payoffAmount = db.GetCurrentPayOffAmountFunction(1000, DateTime.Now);
I always get an error:
InvalidOperationException: The specified cast from a materialized 'System.Decimal' type to the 'System.String' type is not valid.
Now, I can use the first method to get my value and it works fine, but it feels wrong to me to get a random item just so I can call my function. Has anyone seen this? What am I doing wrong here?