How can i access abstract class in BLL ? i shouldn't see GenAccessor in BLL it must be private class GenAccessor . i should access Save method over _AccessorForSQL. ok?
MY BLL cs:
public class AccessorForSQL: GenoTip.DAL._AccessorForSQL
{
public bool Save(string Name, string SurName, string Adress)
{
ListDictionary ld = new ListDictionary();
ld.Add("@Name", Name);
ld.Add("@SurName", SurName);
ld.Add("@Adress", Adress);
return **base.Save("sp_InsertCustomers", ld, CommandType.StoredProcedure);**
}
}
i can not access base.Save....????????
it is my DAL Layer:
开发者_运维技巧namespace GenoTip.DAL
{
public abstract class _AccessorForSQL
{
public abstract bool Save(string sp, ListDictionary ld, CommandType cmdType);
public abstract bool Update();
public abstract bool Delete();
public abstract DataSet Select();
}
private class GenAccessor : _AccessorForSQL
{
DataSet ds;
DataTable dt;
public override bool Save(string sp, ListDictionary ld, CommandType cmdType)
{
SqlConnection con = null;
SqlCommand cmd = null;
SqlDataReader dr = null;
try
{
con = GetConnection();
cmd = new SqlCommand(sp, con);
con.Open();
cmd.CommandType = cmdType;
foreach (string ky in ld.Keys)
{
cmd.Parameters.AddWithValue(ky, ld[ky]);
}
dr = cmd.ExecuteReader();
ds = new DataSet();
dt = new DataTable();
ds.Tables.Add(dt);
ds.Load(dr, LoadOption.OverwriteChanges, dt);
}
catch (Exception exp)
{
HttpContext.Current.Trace.Warn("Error in GetCustomerByID()", exp.Message, exp);
}
finally
{
if (dr != null) dr.Close();
if (con != null) con.Close();
}
return (ds.Tables[0].Rows.Count > 0) ? true : false;
}
public override bool Update()
{
return true;
}
public override bool Delete()
{
return true;
}
public override DataSet Select()
{
DataSet dst = new DataSet();
return dst;
}
private static SqlConnection GetConnection()
{
string connStr = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(connStr);
return conn;
}
Scott Ambler: Building Object Applications That Work.
No futher comment - the whole DAL is pretty much a nice demonstration of how NOT to do it. A DAL should have NO (!) reference to the BLL at all. None. The DAL code area should not ahve ANY reference to the BLL layer at all.
In your case I strongly suggest some looks at:
- BLToolkit
- Nhibernate
If you want to access the save method you simply create an instance of your DAL and call the .Save method like so:
using(GenAccessor g = new GenAccessor)
{
g.save(sproc, param2, param3);
}
Your AccessorForSQL
class must also be marked as abstract
since you don't provide any implementation for the abstract methods in the _AccessorForSQL
.
Clarification: the base
keyword cannot be used here because it would indicate that you want to call the specific implementation found in the base class, which obviously doesn't exist since the method is abstract. That said, it doesn't mean you cannot call the method, you just have to drop the base keyword. And again, since you don't implement any of the abstract methods from the base class in the subclass you must mark the subclass as abstract as well. The following should work:
public abstract class AccessorForSQL: GenoTip.DAL._AccessorForSQL
{
public bool Save(string Name, string SurName, string Adress)
{
ListDictionary ld = new ListDictionary();
ld.Add("@Name", Name);
ld.Add("@SurName", SurName);
ld.Add("@Adress", Adress);
return Save("sp_InsertCustomers", ld, CommandType.StoredProcedure);
}
}
You should probably consider using a default implementation in your _AccessorForSQL class. Then you dont need the GenAccessor at all.
By the way, you shouldn't really be using anything web related in your DAL. HttpContext and WebConfigurationManager should be factored out so you can use your DAL layer in other contexts such as WinForms.
namespace GenoTip.DAL
{
public interface IAccessorForSQL
{
bool Delete();
bool Save(string sp, ListDictionary ld, CommandType cmdType);
DataSet Select();
bool Update();
}
public class _AccessorForSQL : IAccessorForSQL
{
private DataSet ds;
private DataTable dt;
public virtual bool Save(string sp, ListDictionary ld, CommandType cmdType)
{
SqlConnection con = null;
SqlCommand cmd = null;
SqlDataReader dr = null;
try
{
con = GetConnection();
cmd = new SqlCommand(sp, con);
con.Open();
cmd.CommandType = cmdType;
foreach (string ky in ld.Keys)
{
cmd.Parameters.AddWithValue(ky, ld[ky]);
}
dr = cmd.ExecuteReader();
ds = new DataSet();
dt = new DataTable();
ds.Tables.Add(dt);
ds.Load(dr, LoadOption.OverwriteChanges, dt);
}
catch (Exception exp)
{
HttpContext.Current.Trace.Warn("Error in GetCustomerByID()", exp.Message, exp);
}
finally
{
if (dr != null)
{
dr.Close();
}
if (con != null)
{
con.Close();
}
}
return (ds.Tables[0].Rows.Count > 0) ? true : false;
}
public abstract bool Update();
public abstract bool Delete();
public abstract DataSet Select();
private static SqlConnection GetConnection()
{
string connStr = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
var conn = new SqlConnection("");
return conn;
}
}
}
You cannot call an abstract method because it does not have an implementation!
Perhaps you want a virtual method?
By the way this line:
return (ds.Tables[0].Rows.Count > 0) ? true : false;
is the same as this:
return (ds.Tables[0].Rows.Count > 0);
精彩评论