Podczas klasy mapowania otrzymuję błąd 'T' musi być typem nie abstrakcyjnym z publicznym konstruktorem bez parametrów w celu użycia go jako parametr "T" w typie generycznym lub metodzie.Błąd odwzorowania klasy: 'T' musi być typem nie abstrakcyjnym z publicznym konstruktorem bez parametrów
Poniżej jest moje SqlReaderBase Klasa
public abstract class SqlReaderBase<T> : ConnectionProvider
{
#region Abstract Methods
protected abstract string commandText { get; }
protected abstract CommandType commandType { get; }
protected abstract Collection<IDataParameter> GetParameters(IDbCommand command);
**protected abstract MapperBase<T> GetMapper();**
#endregion
#region Non Abstract Methods
/// <summary>
/// Method to Execute Select Queries for Retrieveing List of Result
/// </summary>
/// <returns></returns>
public Collection<T> ExecuteReader()
{
//Collection of Type on which Template is applied
Collection<T> collection = new Collection<T>();
// initializing connection
using (IDbConnection connection = GetConnection())
{
try
{
// creates command for sql operations
IDbCommand command = connection.CreateCommand();
// assign connection to command
command.Connection = connection;
// assign query
command.CommandText = commandText;
//state what type of query is used, text, table or Sp
command.CommandType = commandType;
// retrieves parameter from IDataParameter Collection and assigns it to command object
foreach (IDataParameter param in GetParameters(command))
command.Parameters.Add(param);
// Establishes connection with database server
connection.Open();
// Since it is designed for executing Select statements that will return a list of results
// so we will call command's execute reader method that return a Forward Only reader with
// list of results inside.
using (IDataReader reader = command.ExecuteReader())
{
try
{
// Call to Mapper Class of the template to map the data to its
// respective fields
MapperBase<T> mapper = GetMapper();
collection = mapper.MapAll(reader);
}
catch (Exception ex) // catch exception
{
throw ex; // log errr
}
finally
{
reader.Close();
reader.Dispose();
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
connection.Dispose();
}
}
return collection;
}
#endregion
}
Co staram się robić to, jestem executine niektóre polecenia i wypełnienie mojej klasy dynamicznie. Klasa jest podana poniżej:
namespace FooZo.Core
{
public class Restaurant
{
#region Private Member Variables
private int _restaurantId = 0;
private string _email = string.Empty;
private string _website = string.Empty;
private string _name = string.Empty;
private string _address = string.Empty;
private string _phone = string.Empty;
private bool _hasMenu = false;
private string _menuImagePath = string.Empty;
private int _cuisine = 0;
private bool _hasBar = false;
private bool _hasHomeDelivery = false;
private bool _hasDineIn = false;
private int _type = 0;
private string _restaurantImagePath = string.Empty;
private string _serviceAvailableTill = string.Empty;
private string _serviceAvailableFrom = string.Empty;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Address
{
get { return _address; }
set { _address = value; }
}
public int RestaurantId
{
get { return _restaurantId; }
set { _restaurantId = value; }
}
public string Website
{
get { return _website; }
set { _website = value; }
}
public string Email
{
get { return _email; }
set { _email = value; }
}
public string Phone
{
get { return _phone; }
set { _phone = value; }
}
public bool HasMenu
{
get { return _hasMenu; }
set { _hasMenu = value; }
}
public string MenuImagePath
{
get { return _menuImagePath; }
set { _menuImagePath = value; }
}
public string RestaurantImagePath
{
get { return _restaurantImagePath; }
set { _restaurantImagePath = value; }
}
public int Type
{
get { return _type; }
set { _type = value; }
}
public int Cuisine
{
get { return _cuisine; }
set { _cuisine = value; }
}
public bool HasBar
{
get { return _hasBar; }
set { _hasBar = value; }
}
public bool HasHomeDelivery
{
get { return _hasHomeDelivery; }
set { _hasHomeDelivery = value; }
}
public bool HasDineIn
{
get { return _hasDineIn; }
set { _hasDineIn = value; }
}
public string ServiceAvailableFrom
{
get { return _serviceAvailableFrom; }
set { _serviceAvailableFrom = value; }
}
public string ServiceAvailableTill
{
get { return _serviceAvailableTill; }
set { _serviceAvailableTill = value; }
}
#endregion
public Restaurant() { }
}
}
Do wypełniania swoich właściwości klasy dynamicznie mam inną klasę o nazwie MapperBase klasy z następujących metod:
public abstract class MapperBase<T> where T : new()
{
protected T Map(IDataRecord record)
{
T instance = new T();
string fieldName;
PropertyInfo[] properties = typeof(T).GetProperties();
for (int i = 0; i < record.FieldCount; i++)
{
fieldName = record.GetName(i);
foreach (PropertyInfo property in properties)
{
if (property.Name == fieldName)
{
property.SetValue(instance, record[i], null);
}
}
}
return instance;
}
public Collection<T> MapAll(IDataReader reader)
{
Collection<T> collection = new Collection<T>();
while (reader.Read())
{
collection.Add(Map(reader));
}
return collection;
}
}
istnieje inna klasa, która dziedziczy SqlreaderBaseClass nazywa DefaultSearch. Kod jest poniżej
public class DefaultSearch: SqlReaderBase<Restaurant>
{
protected override string commandText
{
get { return "Select Name from vw_Restaurants"; }
}
protected override CommandType commandType
{
get { return CommandType.Text; }
}
protected override Collection<IDataParameter> GetParameters(IDbCommand command)
{
Collection<IDataParameter> parameters = new Collection<IDataParameter>();
parameters.Clear();
return parameters;
}
protected override MapperBase<Restaurant> GetMapper()
{
MapperBase<Restaurant> mapper = new RMapper();
return mapper;
}
}
Ale ilekroć próbowałem budować, otrzymuję błąd „T” musi być non-abstrakcyjny typ z konstruktora bez parametrów publicznej w celu wykorzystania go jako parametr „T” w rodzaju generycznego lub metoda. Nawet T tutaj jest Restauracja ma Konstruktor bez Parameter Public.
Dzięki temu zadziałało. Ale jest jeszcze jeden sposób wywoływania MapperBase w samej SqlReaderBase bez tworzenia Protected Abstract Mapperbase GetMapper(); metoda. –
@Amit: Możesz mieć * oddzielny * parametr typu 'TMapper' z ograniczeniem:' gdzie TMapper: MapperBase, new() ' –
proszę podać mi faktyczną deklarację .. byłoby to gr8 pomoc –