Как настроить созданные объекты данных (платформа Entity Framework)
В этом разделе показано добавление пользовательского метода к автоматически созданному классу данных. Примеры в этом разделе основаны на модели Adventure Works Sales Model. Чтобы запустить код из данного примера, нужно сначала добавить к проекту модель AdventureWorks Sales и настроить его для использования платформы Entity Framework. Для этого выполните инструкции из разделов Как вручную настроить проект Entity Framework и Как определить модель и файлы сопоставления вручную (платформа Entity Framework).
Пример
В данном примере определяется пользовательский метод UpdateOrderTotal для автоматически созданного класса SalesOrderHeader. Этот пользовательский метод изменяет значение свойства TotalDue на основе текущих значений налога, стоимости фрахта и общих сумм по отдельным наименованиям товара. Данный метод определен как разделяемый класс, поэтому он не исчезает, когда класс SalesOrderHeader пересоздается средствами платформы Entity Framework.
Partial Public Class SalesOrderHeader
' Update the order total.
Public Sub UpdateOrderTotal()
Dim newSubTotal As Decimal = 0
' Ideally, this information is available in the EDM.
Dim taxRatePercent As Decimal = GetCurrentTaxRate()
Dim freightPercent As Decimal = GetCurrentFreight()
' If the items for this order are loaded or if the order is
' newly added, then recalculate the subtotal as it may have changed.
If Me.SalesOrderDetails.IsLoaded OrElse EntityState = EntityState.Added Then
For Each item As SalesOrderDetail In Me.SalesOrderDetails
' Calculate line totals for loaded items.
newSubTotal += (item.OrderQty * (item.UnitPrice - item.UnitPriceDiscount))
Next
Me.SubTotal = newSubTotal
End If
' Calculate the new tax amount.
Me.TaxAmt = Me.SubTotal + Decimal.Round((Me.SubTotal * taxRatePercent / 100), 4)
' Calculate the new freight amount.
Me.Freight = Me.SubTotal + Decimal.Round((Me.SubTotal * freightPercent / 100), 4)
' Calculate the new total.
Me.TotalDue = Me.SubTotal + Me.TaxAmt + Me.Freight
End Sub
End Class
public partial class SalesOrderHeader
{
// Update the order total.
public void UpdateOrderTotal()
{
decimal newSubTotal = 0;
// Ideally, this information is available in the EDM.
decimal taxRatePercent = GetCurrentTaxRate();
decimal freightPercent = GetCurrentFreight();
// If the items for this order are loaded or if the order is
// newly added, then recalculate the subtotal as it may have changed.
if (this.SalesOrderDetails.IsLoaded ||
EntityState == EntityState.Added)
{
foreach (SalesOrderDetail item in this.SalesOrderDetails)
{
// Calculate line totals for loaded items.
newSubTotal += (item.OrderQty *
(item.UnitPrice - item.UnitPriceDiscount));
}
this.SubTotal = newSubTotal;
}
// Calculate the new tax amount.
this.TaxAmt = this.SubTotal
+ Decimal.Round((this.SubTotal * taxRatePercent / 100), 4);
// Calculate the new freight amount.
this.Freight = this.SubTotal
+ Decimal.Round((this.SubTotal * freightPercent / 100), 4);
// Calculate the new total.
this.TotalDue = this.SubTotal + this.TaxAmt + this.Freight;
}
}
В этом примере изменяется заказ, а затем вызывается метод UpdateOrderTotal объекта SalesOrderHeader для изменения свойства TotalDue. Объект TotalDue имеет атрибут StoreGeneratedPattern="computed"
, который применен в SSDL-файле, поэтому при вызове SaveChanges обновленное значение не сохраняется на сервере. Если этот атрибут не задан, при попытке изменения вычисляемого столбца на сервере будет создано исключение UpdateException.
Dim orderId As Integer = 43662
Using context As New AdventureWorksEntities()
' Return an order and its items.
Dim order As SalesOrderHeader = context.SalesOrderHeaders.Include("SalesOrderDetails") _
.Where("it.SalesOrderID = @orderId", _
New ObjectParameter("orderId", orderId)).First()
Console.WriteLine("The original order total was: " & order.TotalDue)
' Update the order status.
order.Status = 1
' Increase the quantity of the first item, if one exists.
If order.SalesOrderDetails.Count > 0 Then
order.SalesOrderDetails.First().OrderQty += 1
End If
' Increase the shipping amount by 10%.
order.Freight = Decimal.Round(order.Freight * CDec(1.1), 4)
' Call the custom method to update the total.
order.UpdateOrderTotal()
Console.WriteLine("The calculated order total is: " & order.TotalDue)
' Save changes in the object context to the database.
Dim changes As Integer = context.SaveChanges()
' Refresh the order to get the computed total from the store.
context.Refresh(RefreshMode.StoreWins, order)
Console.WriteLine("The store generated order total is: " & order.TotalDue)
End Using
int orderId = 43662;
using (AdventureWorksEntities context =
new AdventureWorksEntities())
{
// Return an order and its items.
SalesOrderHeader order =
context.SalesOrderHeaders
.Include("SalesOrderDetails")
.Where("it.SalesOrderID = @orderId",
new ObjectParameter("orderId", orderId)).First();
Console.WriteLine("The original order total was: "
+ order.TotalDue);
// Update the order status.
order.Status = 1;
// Increase the quantity of the first item, if one exists.
if (order.SalesOrderDetails.Count > 0)
{
order.SalesOrderDetails.First().OrderQty += 1;
}
// Increase the shipping amount by 10%.
order.Freight =
Decimal.Round(order.Freight * (decimal)1.1, 4);
// Call the custom method to update the total.
order.UpdateOrderTotal();
Console.WriteLine("The calculated order total is: "
+ order.TotalDue);
// Save changes in the object context to the database.
int changes = context.SaveChanges();
// Refresh the order to get the computed total from the store.
context.Refresh(RefreshMode.StoreWins, order);
Console.WriteLine("The store generated order total is: "
+ order.TotalDue);
}
См. также
Основные понятия
Настройка объектов (платформа Entity Framework)
Определение бизнес-логики (платформа Entity Framework)