Entity Framework 4 – Funktionsimport erstellen
Funktionsimporte für Entitäten stellen in EF1 keine Probleme dar. Nach dem Erstellen des Funktionsimports wird in der Edmx-Datei die Prozedur angelegt und der entsprechende Code generiert.
Bei Auswahl von Entitäten als Rückgabetypen werden in der .edmx-Datei folgende Code-Elemente angelegt:
edmx (xml) Conceptual Model <FunctionImport Name="GetStaffs " EntitySet ="tabStaff " ReturnType ="Collection ( TestModel . tabStaff )" /> Mappings <FunctionImportMapping FunctionImportName="GetStaffs" FunctionName="TestModel.Store. uspGetStaffs " />
Dazu wird folgender C#-Code generiert:
C# (generiert)
public global:: System. Data.Objects.ObjectResult<tabStaff> GetStaffs()
{
return base.ExecuteFunction<tabStaff>("GetStaffs");
}
Diese Methode kann anschliessend über den Objektcontext aufgerufen werden. Bei den beiden anderen Rückgabetypen Skalare und Keine sieht das Ganze in der ersten Version ein wenig anders aus.
Die Vorgehensweise ist gleich, die Funktionsimport-Maske wird geöffnet und die gewünschten Informationen ausgewählt.
Bei Auswahl eines Skalaren Rückgabetypen werden die Funktionsimport-Elemente in der Edmx-Datei erstellt.
edmx (xml)
Conceptual Model
<FunctionImport Name="GetStaffHobby" ReturnType="Collection(String)">
<Parameter Name="StaffId " Mode="In" Type ="Int32" />
</FunctionImport >
Mappings
<FunctionImportMapping FunctionImportName="GetStaffHobby" FunctionName="TestModel.Store. uspGetStaffHobby " />
Die passende Methode für den Objektcontext wird man jedoch nicht finden. Um diese Funktionalität doch zu erreichen, nutze ich folgenden Workaround in EF1. Für den Objektcontext lege ich immer eine Partial-Klasse an, die folgende Basismethoden enthält.
C# Workaroundbasis
namespace Test
{
using System;
using System.Data;
using System.Data.Common;
using System.Data.EntityClient;
public partial class TestEntities2
{
private T ExecuteFunction<T>(string functionname, DbParameter[] parameters)
{
DbCommand cmd = ((EntityConnection) this.Connection).CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange(parameters);
cmd.CommandText = String.Format("{0}.{1}", this.DefaultContainerName, functionname);
cmd.CommandTimeout = 0;
try
{
if (cmd.Connection.State == ConnectionState.Closed)
{
cmd.Connection.Open();
}
var obj = cmd.ExecuteScalar();
return (T) obj;
}
catch (Exception)
{
throw;
}
finally
{
cmd.Connection.Close();
}
}
private void ExecuteVoidFunction(string functionname, DbParameter[] parameters)
{
DbCommand cmd = ((EntityConnection) this.Connection).CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
if (parameters != null)
{
cmd.Parameters.AddRange(parameters);
}
cmd.CommandText = String.Format("{0}.{1}", this.DefaultContainerName, functionname);
try
{
if (cmd.Connection.State == ConnectionState.Closed)
{
cmd.Connection.Open();
}
cmd.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
finally
{
cmd.Connection.Close();
}
}
}
}
Auf diese kann dann immer zurückgegriffen werden, wenn Funktionsimporte benötigt werden, für die kein Code generiert wird. Damit die Prozedur GetStaffHobby über den Objektcontext angelegt werden kann, muss folgende Methode in einer Partial-Klasse des Objektcontexts erstellt werden:
C# (Workaround)
public string GetStaffHobby(int staffId)
{
var param = new EntityParameter("StaffId", DbType.Int32);
param.Value = staffId;
return this.ExecuteFunction<string>("GetStaffHobby", new[] { param });
}
Dieser Mehraufwand ist mit EF 4 nicht mehr notwendig.
Neu wird in diesem Fall der passende Code generiert.
C# (generiert)
public ObjectResult<global::System.String> GetStaffHobby(Nullable<global::System.Int32> staffId )
{
ObjectParameter staffIdParameter;
if (staffId.HasValue)
{
staffIdParameter = new ObjectParameter("StaffId", staffId);
}
else
{
staffIdParameter = new ObjectParameter("StaffId", typeof(global::System. Int32));
}
return base.ExecuteFunction<global::System.String>("GetStaffHobby", staffIdParameter);
}
Hilfreich ist auch die Möglichkeit, dass die Spalteninformationen der gespeicherten Prozedur abgefragt werden können.
Wieder ein Workaround weniger.
- 0 Kommentar(e)





Mein Kommentar