解决方法
我发现了一种我认为最好的模式 – 至少在我的情况下.
我使用部分类扩展实体类.我使用部分类,因此实体的签名不会更改(请参阅Delete方法中的DeleteOnSubmit调用).
我已经做了一个小例子.这是数据库和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(); }