EF Core 3.1을 사용하고 있으며 다음 저장 프로 시저 호출이 있습니다.
public async Task<string> UserSessionGet(string user, string password, string ip)
{
IList<SessionItem> lst = null;
try
{
// Processing.
string sqlQuery = "EXEC [dbo].[GetUserSession] @UserLogin, @UserPassword, @IP, @ErrorCode OUTPUT, @ErrorText OUTPUT";
int errorCode = 0;
string errorText = string.Empty;
lst = await this.Set<SessionItem>().FromSqlRaw(sqlQuery,
new SqlParameter("@UserLogin", user ?? (object)DBNull.Value),
new SqlParameter("@UserPassword", password ?? (object)DBNull.Value),
new SqlParameter("@IP", ip ?? (object)DBNull.Value),
new SqlParameter("@ErrorCode", errorCode) { Direction = ParameterDirection.Output},
new SqlParameter("@ErrorText", errorText) { Direction = ParameterDirection.Output }
).ToListAsync();
}
catch (Exception ex)
{
throw ex;
}
// Info.
return lst.FirstOrDefault()?.Session;
}
엔티티 :
public class SessionItem
{
[NotMapped]
public string Session { get; set; }
}
설정 :
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<SessionItem>().HasNoKey();
}
이 코드를 실행하려고하면 예외가 발생합니다.
시퀀스에 요소가 없습니다.
NotMapped
로그인 실패시 주석을 제거하면 예외가 발생합니다.
필수 열 'Session'이 'FromSql'연산의 결과에 없습니다.
사용자가 잘못된 비밀번호 또는 사용자 이름 만 입력 @ErrorCode
하여 @ErrorText
반환되지만 데이터가 전혀없는 경우
https://i.ibb.co/pf4KzHz/Failure-Login.png
성공 호출시 하나의 열만 반환되며 Session
.
https://i.ibb.co/tL3CR1H/2020-09-06-07-57-12.png
내가 무엇을하여야한다?
다른 열 집합과 동일한 동작을 가진 다른 저장 프로 시저가 있습니다.
내 자신의 확장 클래스를 작성했습니다.
public static class DataModelExtensions
{
public static DbCommand LoadStoredProc(
this DbContext context, string storedProcName)
{
var cmd = context.Database.GetDbConnection().CreateCommand();
cmd.CommandText = storedProcName;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
return cmd;
}
public static DbCommand LoadSql(this DbContext context, string sql)
{
var cmd = context.Database.GetDbConnection().CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = System.Data.CommandType.Text;
return cmd;
}
public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, object paramValue, ParameterDirection direction = ParameterDirection.Input, int ?size = null)
{
if (string.IsNullOrEmpty(cmd.CommandText))
throw new InvalidOperationException(
"Call LoadStoredProc before using this method");
var param = cmd.CreateParameter();
param.ParameterName = paramName;
param.Value = paramValue;
param.Direction = direction;
if (size.HasValue)
param.Size = size.Value;
cmd.Parameters.Add(param);
return cmd;
}
private static List<T> MapToList<T>(this DbDataReader dr, int? errorCode, string errorText)
{
var objList = new List<T>();
var props = typeof(T).GetRuntimeProperties();
var colMapping = dr.GetColumnSchema()
.Where(x => props.Any(y => y.Name.ToLower() == x.ColumnName.ToLower()))
.ToDictionary(key => key.ColumnName.ToLower());
int rowNumber = 1;
T obj = Activator.CreateInstance<T>();
if (dr.HasRows)
{
while (dr.Read())
{
obj = Activator.CreateInstance<T>();
foreach (var prop in props)
{
if (colMapping.ContainsKey(prop.Name.ToLower()))
{
object val;
var propName = prop.Name.ToLower();
val = dr.GetValue(colMapping[propName].ColumnOrdinal.Value);
prop.SetValue(obj, val == DBNull.Value ? null : val);
}
}
rowNumber++;
objList.Add(obj);
}
}
else
{
foreach (var prop in props)
{
var propName = prop.Name;
if (propName == "ErrorCode")
prop.SetValue(obj, errorCode);
else if (propName == "ErrorText")
prop.SetValue(obj, errorText);
}
objList.Add(obj);
}
return objList;
}
public static async Task<List<T>> Execute<T>(this DbCommand command)
{
using (command)
{
//System.Diagnostics.Debug.WriteLine(command.ToLog());
if (command.Connection.State == System.Data.ConnectionState.Closed)
command.Connection.Open();
try
{
using (var reader = await command.ExecuteReaderAsync())
{
return reader.MapToList<T>((int?)command.Parameters["@ErrorCode"].Value, (string)command.Parameters["@ErrorText"].Value);
}
}
catch (Exception e)
{
throw (e);
}
finally
{
command.Connection.Close();
}
}
}
public static async Task<bool> HasRows(this DbCommand command)
{
using (command)
{
if (command.Connection.State == System.Data.ConnectionState.Closed)
command.Connection.Open();
try
{
using (var reader = await command.ExecuteReaderAsync())
{
return reader.HasRows;
}
}
catch (Exception e)
{
throw (e);
}
finally
{
command.Connection.Close();
}
}
}
public static async Task<bool> QueryHasRows(this DbContext context, string sql)
{
return await context.LoadSql(sql).HasRows();
}
public static string ToLog(this DbCommand command)
{
//-- @p5: Input Int (Size = -1; Prec = 0; Scale = 0) [194]
StringBuilder sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine(command.CommandText);
foreach(DbParameter parameter in command.Parameters)
{
if(parameter.Value != null && !string.IsNullOrEmpty(parameter.Value.ToString()))
{
sb.AppendLine($"{parameter.ParameterName}={parameter.Value}");
//sb.AppendLine($"-- {parameter.ParameterName}: {parameter.Direction} {parameter.DbType} (Size = {parameter.Size}; Prec = {parameter.Precision}; Scale = {parameter.Scale}) [{parameter.Value}]");
}
}
return sb.ToString();
}
}
사용 예 :
public async Task<string> UserSessionGet(string user, string password, string ip)
{
//SessionItem lst = null;
IList<SessionItem> lst = null;
try
{
int errorCode = 0;
string errorText = string.Empty;
List<SessionItem> result = new List<SessionItem>();
result = await this.LoadStoredProc("UserSessionGet")
.WithSqlParam("@UserLogin", user)
.WithSqlParam("@UserPassword", password)
.WithSqlParam("@IP", ip)
.WithSqlParam("@ErrorCode", errorCode, ParameterDirection.Output)
.WithSqlParam("@ErrorText", errorText, ParameterDirection.Output, 255)
.Execute<SessionItem>();
if (result.Count == 1)
{
return result[0].Session;
}
//return result.FirstOrDefault(x => x.iscurrent.ToLower() == "да");
return string.Empty;
}
catch (Exception ex)
{
throw ex;
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다