Bagikan melalui


Cara: Memanggil Fungsi yang Ditentukan-Model sebagai Metode Objek

Topik ini menjelaskan cara memanggil fungsi yang ditentukan model sebagai metode pada objek ObjectContext atau sebagai metode statis pada kelas kustom. Fungsi yang ditentukan model adalah fungsi yang didefinisikan dalam model konseptual. Prosedur dalam topik menjelaskan cara memanggil fungsi ini secara langsung alih-alih memanggilnya dari kueri LINQ ke Entitas. Untuk informasi tentang memanggil fungsi yang ditentukan model dalam kueri LINQ ke Entitas, lihat Cara: Memanggil Fungsi yang Ditentukan Model dalam Kueri.

Baik Anda memanggil fungsi yang ditentukan model sebagai metode ObjectContext atau sebagai metode statis pada kelas kustom, Anda harus terlebih dahulu memetakan metode tersebut ke fungsi yang ditentukan model dengan EdmFunctionAttribute. Namun, saat Anda mendefinisikan metode pada kelas ObjectContext, Anda harus menggunakan properti QueryProvider untuk mengekspos penyedia LINQ, sedangkan saat Anda mendefinisikan metode statis pada kelas kustom, Anda harus menggunakan properti Provider untuk mengekspos penyedia LINQ. Untuk informasi selengkapnya, lihat contoh yang mengikuti prosedur di bawah ini.

Prosedur di bawah ini memberikan kerangka tingkat tinggi untuk memanggil fungsi yang ditentukan model sebagai metode pada objek ObjectContext dan sebagai metode statis pada kelas kustom. Contoh berikut memberikan detail lebih lanjut tentang langkah-langkah dalam prosedur. Prosedur mengasumsikan bahwa Anda telah mendefinisikan fungsi dalam model konseptual. Untuk informasi selengkapnya, lihat Cara: Mendefinisikan Fungsi Kustom dalam Model Konseptual.

Untuk memanggil fungsi yang ditentukan model sebagai metode pada objek ObjectContext

  1. Tambahkan file sumber untuk memperluas kelas parsial yang berasal dari kelas ObjectContext, yang dibuat secara otomatis oleh alat Entity Framework. Mendefinisikan stub runtime bahasa umum dalam file sumber terpisah akan mencegah perubahan hilang saat file diregenerasi.

  2. Tambahkan metode runtime bahasa umum (CLR) ke kelas ObjectContext Anda yang melakukan hal berikut:

    • Memetakan ke fungsi yang didefinisikan dalam model konseptual. Untuk memetakan metode, Anda harus menerapkan EdmFunctionAttribute ke metode itu. Perhatikan bahwa parameter NamespaceName dan FunctionName dari atribut adalah nama namespace layanan model konseptual dan nama fungsi dalam model konseptual. Resolusi nama fungsi untuk LINQ peka huruf besar/kecil.

    • Mengembalikan hasil metode Execute yang dikembalikan oleh properti QueryProvider.

  3. Panggil metode sebagai anggota pada instans kelas ObjectContext.

Untuk memanggil fungsi yang ditentukan model sebagai metode statis pada kelas kustom

  1. Tambahkan kelas ke aplikasi Anda dengan metode statis yang melakukan hal berikut:

    • Memetakan ke fungsi yang didefinisikan dalam model konseptual. Untuk memetakan metode, Anda harus menerapkan EdmFunctionAttribute ke metode itu. Perhatikan bahwa parameter NamespaceName dan FunctionName dari atribut adalah nama namespace layanan model konseptual dan nama fungsi dalam model konseptual.

    • Menerima argumen IQueryable.

    • Mengembalikan hasil metode Execute yang dikembalikan oleh properti Provider.

  2. Memanggil metode sebagai anggota metode statis pada kelas kustom

Contoh 1

Memanggil Fungsi yang Ditentukan Model sebagai Metode pada Objek ObjectContext

Contoh berikut menunjukkan cara memanggil fungsi yang ditentukan model sebagai metode pada objek ObjectContext. Contoh menggunakan Model Penjualan AdventureWorks.

Pertimbangkan fungsi model konseptual di bawah ini yang mengembalikan pendapatan produk untuk produk tertentu. (Untuk informasi tentang menambahkan fungsi ke model konseptual Anda, lihat Cara: Menentukan Fungsi Kustom dalam Model Konseptual.)

<Function Name="GetProductRevenue" ReturnType="Edm.Decimal">
  <Parameter Name="productID" Type="Edm.Int32" />
  <DefiningExpression>
    SUM( SELECT VALUE((s.UnitPrice - s.UnitPriceDiscount)  * s.OrderQty)
    FROM AdventureWorksEntities.SalesOrderDetails as s
    WHERE s.ProductID = productID)
  </DefiningExpression>
</Function>

Contoh 2

Kode berikut menambahkan metode ke kelas AdventureWorksEntities yang memetakan ke fungsi model konseptual di atas.

public partial class AdventureWorksEntities : ObjectContext
{
    [EdmFunction("AdventureWorksModel", "GetProductRevenue")]
    public decimal? GetProductRevenue(int productId)
    {
        return this.QueryProvider.Execute<decimal?>(Expression.Call(
            Expression.Constant(this),
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(productId, typeof(int))));
    }
}
Partial Public Class AdventureWorksEntities
    Inherits ObjectContext

    <EdmFunction("AdventureWorksModel", "GetProductRevenue")>
    Public Function GetProductRevenue(ByVal details As _
                    IQueryable(Of SalesOrderDetail)) As _
                    System.Nullable(Of Decimal)
        Return Me.QueryProvider.Execute(Of System.Nullable(Of Decimal)) _
            (Expression.[Call](Expression.Constant(Me), _
            DirectCast(MethodInfo.GetCurrentMethod(), MethodInfo), _
            Expression.Constant(details, GetType(IQueryable(Of SalesOrderDetail)))))
    End Function
End Class

Contoh 3

Kode berikut memanggil metode di atas guna menampilkan pendapatan produk untuk produk tertentu:

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    Console.WriteLine(AWEntities.GetProductRevenue(productId));
}
Using AWEntities As New AdventureWorksEntities()

    Dim productId As Integer = 776

    Dim details = From s In AWEntities.SalesOrderDetails _
                  Where s.ProductID = productId _
                  Select s

    Console.WriteLine(AWEntities.GetProductRevenue(details))
End Using

Contoh 4

Contoh berikut menunjukkan cara memanggil fungsi yang ditentukan model yang mengembalikan koleksi (sebagai objek IQueryable<T>). Pertimbangkan fungsi model konseptual di bawah ini yang mengembalikan semua SalesOrderDetails untuk ID Produk tertentu.

<Function Name="GetDetailsById" 
          ReturnType="Collection(AdventureWorksModel.SalesOrderDetail)">
  <Parameter Name="productID" Type="Edm.Int32" />
  <DefiningExpression>
    SELECT VALUE s
    FROM AdventureWorksEntities.SalesOrderDetails AS s
    WHERE s.ProductID = productID
  </DefiningExpression>
</Function>

Contoh 5

Kode berikut menambahkan metode ke kelas AdventureWorksEntities yang memetakan ke fungsi model konseptual di atas.

public partial class AdventureWorksEntities : ObjectContext
{
    [EdmFunction("AdventureWorksModel", "GetDetailsById")]
    public IQueryable<SalesOrderDetail> GetDetailsById(int productId)
    {
        return this.QueryProvider.CreateQuery<SalesOrderDetail>(Expression.Call(
            Expression.Constant(this),
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(productId, typeof(int))));
    }
}
Partial Public Class AdventureWorksEntities
    Inherits ObjectContext
    <EdmFunction("AdventureWorksModel", "GetDetailsById")> _
    Public Function GetDetailsById(ByVal productId As Integer) _
            As IQueryable(Of SalesOrderDetail)
        Return Me.QueryProvider.CreateQuery(Of SalesOrderDetail) _
            (Expression.[Call](Expression.Constant(Me), _
             DirectCast(MethodInfo.GetCurrentMethod(), MethodInfo), _
             Expression.Constant(productId, GetType(Integer))))
    End Function
End Class

Contoh 6

Kode berikut memanggil metode. Perhatikan bahwa kueri IQueryable<T> yang dikembalikan akan disempurnakan lebih lanjut untuk mengembalikan total baris untuk setiap SalesOrderDetail.

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    var lineTotals = AWEntities.GetDetailsById(productId).Select(d =>d.LineTotal);

    foreach(var lineTotal in lineTotals)
    {
        Console.WriteLine(lineTotal);
    }
}
Using AWEntities As New AdventureWorksEntities()
    Dim productId As Integer = 776

    Dim lineTotals = AWEntities.GetDetailsById(productId).[Select](Function(d) d.LineTotal)

    For Each lineTotal In lineTotals
        Console.WriteLine(lineTotal)
    Next

Contoh 7

Memanggil Fungsi yang Ditentukan Model sebagai Metode Statis pada Kelas Kustom

Contoh berikutnya menunjukkan cara memanggil fungsi yang ditentukan model sebagai metode statis pada kelas kustom. Contoh menggunakan Model Penjualan AdventureWorks.

Catatan

Saat Anda memanggil fungsi yang ditentukan model sebagai metode statis pada kelas kustom, fungsi yang ditentukan model harus menerima koleksi dan mengembalikan agregasi nilai dalam koleksi.

Pertimbangkan fungsi model konseptual di bawah ini yang mengembalikan pendapatan produk untuk koleksi SalesOrderDetail. (Untuk informasi tentang menambahkan fungsi ke model konseptual Anda, lihat Cara: Menentukan Fungsi Kustom dalam Model Konseptual.)

<Function Name="GetProductRevenue" ReturnType="Edm.Decimal">
  <Parameter Name="details" Type="Collection(AdventureWorksModel.SalesOrderDetail)" />
  <DefiningExpression>
    SUM( SELECT VALUE((s.UnitPrice - s.UnitPriceDiscount)  * s.OrderQty)
    FROM details as s)
  </DefiningExpression>
</Function>

Contoh 8

Kode berikut menambahkan kelas ke aplikasi Anda yang berisi metode statis yang memetakan ke fungsi model konseptual di atas.

public class MyClass
{
    [EdmFunction("AdventureWorksModel", "GetProductRevenue")]
    public static decimal? GetProductRevenue(IQueryable<SalesOrderDetail> details)
    {
        return details.Provider.Execute<decimal?>(Expression.Call(
            (MethodInfo)MethodInfo.GetCurrentMethod(),
            Expression.Constant(details, typeof(IQueryable<SalesOrderDetail>))));
    }
}
Public Class [MyClass]
    <EdmFunction("AdventureWorksModel", "GetProductRevenue")> _
    Public Shared Function GetProductRevenue(ByVal details As _
                IQueryable(Of SalesOrderDetail)) As _
                System.Nullable(Of Decimal)
        Return details.Provider.Execute(Of System.Nullable(Of Decimal)) _
            (Expression.[Call](DirectCast(MethodInfo.GetCurrentMethod(), MethodInfo), _
            Expression.Constant(details, GetType(IQueryable(Of SalesOrderDetail)))))
    End Function
End Class

Contoh 9

Kode berikut memanggil metode di atas guna menampilkan pendapatan produk untuk koleksi SalesOrderDetail:

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
    int productId = 776;

    var details = from s in AWEntities.SalesOrderDetails
                  where s.ProductID == productId select s;

    Console.WriteLine(MyClass.GetProductRevenue(details));
}
Using AWEntities As New AdventureWorksEntities()
    Dim productId As Integer = 776

    Dim details = From s In AWEntities.SalesOrderDetails _
                  Where s.ProductID = productId _
                  Select s

    Console.WriteLine([MyClass].GetProductRevenue(details))
End Using

Lihat juga