如何在ASP.NET中改进我的数据访问类

时间:2012-02-29 06:12:32

标签: asp.net

我已经编写了一段时间,但仍然认为自己是初学者。我使用非常简单的ADO.NET类和内置的SQL语句。我想听听社群关于我做错了什么以及如何改进的建议,以及建议的后续步骤是将我的编码纳入现行标准。

我真的很想尝试使用EF,虽然我似乎无法找到适合我的BLL和DAL类的教程,所以会喜欢指向正确方向的指针。

基本上如果我有礼物,我会创建一个礼物类(BLL \ Gift.cs):

using MyProject.DataAccessLayer;

namespace MyProject.BusinessLogicLayer
{
public class Gift
{

    public int GiftID { get; set; }
    public string GiftName { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }

    public static Gift GetGiftByID(int GiftID)
    {
        GiftDAL dataAccessLayer = new GiftDAL();
        return dataAccessLayer.GiftsSelectByID(GiftID);
    }

    public void DeleteGift(Gift myGift)
    {
        GiftDAL dataAccessLayer = new GiftDAL();
        dataAccessLayer.DeleteGift(myGift);
    }

    public bool UpdateGift(Gift myGift)
    {
        GiftDAL dataAccessLayer = new GiftDAL();
        return dataAccessLayer.UpdateGift(myGift);
    }

    public int InsertGift(string GiftName, string Description, decimal Price)
    {
        Gift myGift = new Gift();
        myGift.GiftName = GiftName;
        myGift.Description = Description;
        myGift.Price = Price;

        GiftDAL dataAccessLayer = new GiftDAL();
        return dataAccessLayer.InsertGift(myGift);
    }
}
}

然后我有一个DAL类,它保存我的连接字符串(DAL \ sqlDAL.css):

namespace MyProject.DataAccessLayer
{
public class SqlDataAccessLayer
{
    public readonly string _connectionString = string.Empty;

    public SqlDataAccessLayer()
    {
        _connectionString = WebConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
        if (string.IsNullOrEmpty(_connectionString))
        {
            throw new Exception("No database connection String found");
        }
    }
}
}

然后是一个DAL类(DAL \ giftDAL.cs),其中我展示了几个方法(更新和删除):

using MyProject.BusinessLogicLayer;

namespace MyProject.DataAccessLayer
{
public class GiftDAL : SqlDataAccessLayer
{
    public bool UpdateGift(Gift GifttoUpdate)
    {
        string UpdateString = "";
        UpdateString += "UPDATE Gifts SET";
        UpdateString += "GiftName = @GiftName";
        UpdateString += ",Description = @Description ";
        UpdateString += ",Price = @Price ";
        UpdateString += " WHERE GiftID = @GiftID";

        int RowsAffected = 0;

        try
        {
            using (SqlConnection con = new SqlConnection(_connectionString))
            {
                using (SqlCommand cmd = new SqlCommand(UpdateString, con))
                {
                    cmd.Parameters.AddWithValue("@GiftName", GifttoUpdate.GiftName);
                    cmd.Parameters.AddWithValue("@Description", GifttoUpdate.Description);
                    cmd.Parameters.AddWithValue("@Price ", GifttoUpdate.Price);
                    cmd.Parameters.AddWithValue("@GiftID", GifttoUpdate.GiftID);
                    con.Open();
                    RowsAffected = cmd.ExecuteNonQuery();
                }
            }
        }
        catch (Exception ex)
        {
            Utils.LogError(ex.Message, ex.InnerException == null ? "N/A" : ex.InnerException.Message, ex.StackTrace);
        }

        return (RowsAffected == 1);

    }

    public void DeleteGift(Gift GifttoDelete)
    {
        string DeleteString = "";
        DeleteString += "DELETE FROM GIFTS WHERE GIFTID = @GiftID";

        try
        {
            using (SqlConnection con = new SqlConnection(_connectionString))
            {
                using (SqlCommand cmd = new SqlCommand(DeleteString, con))
                {
                    cmd.Parameters.AddWithValue("@GiftID", GifttoDelete.GiftID);
                    con.Open();
                    cmd.ExecuteNonQuery();

                }
            }
        }
        catch (Exception ex)
        {
            Utils.LogError(ex.Message, ex.InnerException == null ? "N/A" : ex.InnerException.Message, ex.StackTrace);
        }
    }


}
}

所以看一下,你会如何推荐我改进代码(如果我继续使用ADO.NET)以及我的下一步将学习EF - 还是有更好的替代方案?

干杯, 罗比

3 个答案:

答案 0 :(得分:2)

如果您想坚持使用ADD.NET,那么为什么不从Microsoft Enterprise Library查看Data Application Block(当前版本是2011年5月5日) - 它将允许您编写供应商(MS-SQL / Oracle)等)中性代码很容易,大部分锅炉板编码都被包裹起来。

This可能是一个最简单/最短的教程,我可以帮助您入门。但是,MSDN链接有大量信息,请参阅关键场景部分以快速启动。

另一个建议是使用TransactionScope来管理事务(而不是直接使用DbTransaction对象)。

所有我建议使用Entity Framework(或任何类似的OR映射工具 - 例如检查NHibernet),因为那样你就不必编写基本CRUD操作的典型代码了。就你的困境而言,这里有一个基本的代码片段,可以帮助你入门 - 我使用的是带有Code-First方法的EF 4.1,POCO实体和Fluent API:

实体:

public class Gift
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
}

数据访问层:

public class MyDbContext : DbContext
{
   public DbSet<Gift> Gifts { get; set; }

   public MyDbContext () : base("name=[ConnStringName]") {}

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
      // Fluent API to provide mapping - you may use attributes in entity class
      var giftConfig = modelBuilder.Entity<Gift>();
      giftConfig.Property(p => p.Id).HasColumnName("GiftID");
      giftConfig.Property(p => p.Name).HasColumnName("GiftName");
      giftConfig.Property(p => p.Description).HasColumnName("Description");
      giftConfig.Property(p => p.Price).HasColumnName("Price");
      giftConfig.HasKey(p => p.Id);

      base.OnModelCreating(modelBuilder); 
   }
}

业务层:

public static class GiftManager
{
   public static Gift GetById(int id)
   {
      using(var db = new MyDbContext())
      {
         return db.Gifts.Find(id);
      }
   }

   public static void Add(Gift gift)
   {
      using(var db = new MyDbContext())
      {
         // do validation
         ...

         db.Gifts.Add(gift);

         // do auditing
         ...

         db.SaveChanges();
      }
   }

   public static void Update(Gift gift)
   {
      using(var db = new MyDbContext())
      {
         // do validation
         ...

         var entity = db.Sessions.Find(gift.Id);
         entity.Name = gift.Name;
         entity.Description = gift.Description;
         entity.Price = gift.Price;

         // do auditing
         ...

         db.SaveChanges();
      }
   }

}

答案 1 :(得分:2)

对我来说,一件重要的事情(对我来说)是一个可测试的课程。我在你的代码中看到了很多显式的对象构造。您的礼物BL类明确依赖于GiftDAL,这使得测试Gift类非常困难。尝试通过对GiftDAL(例如接口)进行抽象来减少类之间的耦合,并将其从外部提供给Gift(Dependency Injection)。

关于良好软件设计原则的好书是Clean Code by Robert C. Martin。他建立了SOLID原则。看看吧!

另外,请注意,您现在在业务逻辑类(或称为域模型)中包含持久性。这可以完成(Active Record),但是现在人们通常会选择不同的方法,将域模型与任何基础架构分开。宽泛的想法是:对象需要以某种方式存储的事实很重要,但对于业务逻辑本身并不重要,因此应尽可能分离关注点。对于.NET Object Relational MapperNHibernateEntity Framework通常是OR映射器的两个示例。

答案 2 :(得分:0)

我有一个dal类,其方法只返回可绑定的对象,如datatable,List等。没有更多或更少。然后,所有业务逻辑在aspnet应用程序中的代码中自然发生。在大多数情况下制作支持对象的工作量太大而且过度杀伤。我对数据表和列表很满意。