Relational Database: Sql Server 2008 Programming Language: C# Used Framework: Enterprise Library 5.0
How do you access output parameters that are created within the implementation of IParameterMapper?
I'm currently implementing the Repository Pattern. All of our Insert stored procedures contain an output parameter. The output parameter is only present in for those tables who's primary key is an auto generated identity column. All of my stored procedures have associated implementations of IParameterMapper. Each table has an associated TransferObject. Each TransferObject has an associated IRowMapper implementation.
If it is impossible to access the output parameter I believe I only have two other options.
1) Change the stored procedures to return a row that contains the newly created identity as opposed to returning the value through an output parameter. By doing it this way I can use the currently implemented IRowMapper to access the value in the application layer. This way would be more resource intensive but less programming will be needed within the repository.
2) Don't use Database.ExecuteSprocAccessor and just execute the stored procedure "normally"; keeping the stored procedures as they are. This would be the most efficient solution, but require more programming effort.
Below is an example of how we are currently implementing things.
Current Implementation
public class UserRepository : IRepository<User>
{
....
public void Insert(User user)
{
this.database.
}
....
}
public class User : TransferObject
{
public string ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class UserRowMapper : IRowMapper<User>
{
private static readonly UserRowMapper instance = new UserRowMapper();
private UserRowMapper()
{
}
public UserRowMapper Instance
{
get
{
return instance;
}
}
public User MapRow(IDataRecord row)
{
var user = new User
{
ID = row.GetInt32("ID"),
FirstName = row.GetString("FirstName"),
LastName = row.GetString("LastName")
};
}
}
public class InsertUserParameterMapper : IParameterMapper
{
private static readonly InsertUserParameterMapper instance = new InsertUserParameterMapper();
public InsertUserParameterMapper()
{
}
public static InsertUserParameterMapper Instance
{
get
{
return instance;
}
}
public void AssignParameters(DBCommand command, object[] parameterValues)
{
var firstNameParameter = command.CreateParameter();
firstNameParameter.ParameterName = "@firstName";
firstNameParameter.Direction = Parame开发者_JAVA技巧terDirection.Input;
parameter.Value = parameterValues[0];
command.Parameters.Add(firstNameParameter);
var lastNameParameter = command.CreateParameter();
lastNameParameter.ParameterName = "@lastName";
lastNameParameter.Direction = ParameterDirection.Input;
parameter.Value = parameterValues[1];
command.Parameters.Add(lastNameParameter);
var idParameter = command.CreateParameter();
idParameter.ParameterName = "@id";
idParameter.Direction = ParameterDirection.Output;
command.Parameters.Add(idParameter);
}
}
Output parameters were explicitly not included in the accessor design. If your sproc uses them, you're much better off calling the sproc directly.
Considering you're using this with an insert sproc, I suspect it's not returning rows anyway, so the accessor is really not the right abstraction. You want a straight sproc call.
Having said that, you can still use your input mapper if you want - it doesn't have any particular dependency on an accessor, you could call it directly, passing a DbCommand object instead. But db.ExecuteNonQuery does effectively what you're doing already anyway, so you might just get shorter code out of the deal.
精彩评论