Ответ 1
Я нашел образец, который, я думаю, работает лучше всего - в моем случае, по крайней мере.
Я расширяю классы сущностей, используя частичные классы. Я использую частичные классы, поэтому подпись объекта не изменяется (см. Вызов DeleteOnSubmit
в методе Delete
).
Я приготовил небольшой пример. Здесь изображение базы данных и установки LINQ to SQL:
И вот частичный класс, в котором я реализую бизнес-логику:
/// <summary>
/// This class extends BusinessLogicDataContext.Products entity class
/// </summary>
public partial class Product
{
/// <summary>
/// New up a product by column: dbo.Products.ProductId in database
/// </summary>
public Product(Int32 id)
{
var dc = new BusinessLogicDataContext();
// query database for the product
var query = (
from p in dc.Products
where p.ProductId == id
select p
).FirstOrDefault();
// if database-entry does not exist in database, exit
if (query == null) return;
/* if product exists, populate self (this._ProductId and
this._ProductName are both auto-generated private
variables of the entity class which corresponds to the
auto-generated public properties: ProductId and ProductName) */
this._ProductId = query.ProductId;
this._ProductName = query.ProductName;
}
/// <summary>
/// Delete product
/// </summary>
public void Delete()
{
// if self is not poulated, exit
if (this._ProductId == 0) return;
var dc = new BusinessLogicDataContext();
// delete entry in database
dc.Products.DeleteOnSubmit(this);
dc.SubmitChanges();
// reset self (you could implement IDisposable here)
this._ProductId = 0;
this._ProductName = "";
}
}
Использование реализованной бизнес-логики:
// new up a product
var p = new Product(1); // p.ProductId: 1, p.ProductName: "A car"
// delete the product
p.Delete(); // p.ProductId: 0, p.ProductName: ""
Кроме того: классы объектов LINQ to SQL очень открытые. Это означает, что свойство, соответствующее столбцу dbo.Products.ProductId, реализует как getter, так и setter - это поле не должно меняться.
Насколько я знаю, вы не можете переопределять свойства с помощью частичных классов, поэтому я обычно делаю это менеджер, который сужает объект с помощью интерфейса:
public interface IProduct
{
Int32 ProductId { get; }
void Delete();
}