为我的对象实现Save方法

时间:2011-09-01 22:18:36

标签: c# asp.net n-tier-architecture

我正在尝试改进我的应用程序的设计,因此不是从表示层调用DataAccess层。我将尝试从BusinessObjects图层中的对象实现save方法。但我不确定如何通过图层传递对象或它的属性。例如,在我的旧设计中,我只是在表示层中创建我的对象的实例并分配它的属性,然后调用DataAccess方法将此信息保存在数据库中,并将对象作为参数传递,如图所示。

DAL

public static void SaveObject(Object obj)
{
   int id = obj.id;
   string label = obj.label;
}

PL

Object obj = new Object();
obj.id = 1;
obj.label = "test";
DAL.SaveObject(obj); 

但我只想在 PL

中执行此操作
Object obj = new Object();
obj.id = 1;
obj.label = "test";
obj.SaveObject();

这可能吗?我的DAL怎么样?

修改 解释我的要求

我现在将我的代码基于我系统中一个非常重要的对象。

BusinessEntitiesLayer 使用BusinessLogic Layer

namespace BO.Cruises
{
    public class Cruise
    {
        public int ID
        { get; set; }

        public string Name
        { get; set; }

        public int BrandID
        { get; set; }

        public int ClassID
        { get; set; }

        public int CountryID
        { get; set; }

        public string ProfilePic
        { get; set; }

        public bool Hide
        { get; set; }

        public string Description
        { get; set; }

        public int OfficialRate
        { get; set; }

        public string DeckPlanPic
        { get; set; }

        public string CabinsLayoutPic
        { get; set; }

        public List<Itinerary> Itineraries
        { get; set; }

        public List<StatisticFact> Statistics
        { get; set; }

        public List<CabinRoomType> RoomTypesQuantities
        { get; set; }

        public List<CabinFeature> CabinFeatures
        { get; set; }

        public List<CruiseAmenity> Amenities
        { get; set; }

        public List<CruiseService> Services
        { get; set; }

        public List<CruiseEntertainment> Entertainment
        { get; set; }

        public List<CustomerReview> CustomerReviews
        { get; set; }
    }

}

BusinessLogicLayer 使用DataAccessLayer

实际上这个层是为了验证我的对象然后调用DAL方法,但我现在没有实现任何验证,所以我只是用它来调用DAL方法。

    public static void Save(object cruise)
    {
        CruisesDAL.Save(cruise);
    }

DataAccessLayer 尝试引用BussinessEntities,但它给了我循环依赖项错误!

它应该接收对象并将其转换为Cruise实体

    public static void Save(object cruise)
    {
         Cruise c = cruise as Cruise;

         //access the object c properties and save them to the database
    }

我项目的代码示例:

public static List<Cruise> GetCruisesList()
{
    string commandText = "SELECT ID, Name + CASE Hide WHEN 1 Then ' (Hidden)' ELSE '' END AS Name FROM Cruises";
    List<Cruise> cruises = new List<Cruise>();
    Cruise cruise;

    using (SqlConnection connection = new SqlConnection(ConnectionString))
    {
        using (SqlCommand command = new SqlCommand(commandText, connection))
        {
            connection.Open();

            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    cruise = new Cruise();

                    cruise.ID = Convert.ToInt32(reader["ID"]);
                    cruise.Name = reader["Name"].ToString();

                    cruises.Add(cruise);
                }
            }
        }
    }

    return cruises;
}

PresentationLayer 使用BusinessEntities

输入控件(TextBoxes,DropDownList等)

单击保存按钮时,我获取所有值,创建一个Cruise对象并调用Cruise.Save();

3 个答案:

答案 0 :(得分:2)

您应该避免将域模型与持久性逻辑混合使用。 上面给出的例子将成为紧密耦合解决方案。 为了实现.SaveObject(),您可以在BL中创建可以完成工作的扩展方法。

BL *

public static class ObjectPersistanceExtensions{

       public static SaveObejct<T>(this IBaseEntity obj){

            IObjectDal<T> _dal = AvailableSerices.Obtain<IObjectDal<T>>();
            _dal.AddObject(obj);
            _dal.Commit();
       }
}

因此,通过这种方式,您仍然可以向域对象添加工作组,而无需在域对象中耦合逻辑。

答案 1 :(得分:1)

如果您遵循这种模式,您将在对象定义中拥有保存逻辑,因此当您从PL调用时:

obj.SaveObject();

这将发生在对象本身:

public void SaveObject()
{
  DAL.SaveObject(this);
}

并且您的DAL保持与上面显示的相同。

这是一个设计问题,我不会把保存的逻辑放在对象中但我会有一个BusinessManager或一个ObjectMapper来读取DAL并保存到DAL。

一般来说,这是一个很好的做法,可以在同一个地方,BusinessObject或BusinessManager中进行读取或加载和保存,但是如果您添加或更改字段,则可以轻松找到它们并轻松更新。

答案 2 :(得分:1)

将对象本身传递给数据层通常有点时髦。相反,我建议您让对象与数据层进行通信,并让数据层执行其操作。

internal static class DataLayer {

    public static bool Update(int id, string label) {
        // Update your data tier
        return success; // bool whether it succeeded or not
    }
}

internal class BusinessObject {

    public int ID {
        get;
        private set;
    } 

    public string Label {
        get;
        set;
    } 

    public bool Save() {
        return DataLayer.Update(this.ID, this.Label); // return data layer success
    }
}

你这样做的原因是因为你的数据层可能没有对你的业务对象的引用,因此不知道它是什么。您将无法传递对象本身。这是一个常见的场景,因为通常是您的业务对象程序集引用您的数据层程序集。

如果您拥有相同组件中的所有内容,则上述内容不适用。但是,如果您决定将数据层重构为自己的模块(通常是它的结果,并且设计良好),则传递对象将会中断,因为它会丢失对业务对象的引用。

无论哪种方式,您都应该知道,如果添加新字段或成员,则必须更新对象和数据层。当你添加新东西时,这只是给定的。

我可能会为此写一些关于一些好的设计实践的博客,但这是我的建议。