Как сопоставить пользовательский тип на сервере SQL с API EF Fluent для модели? - PullRequest
0 голосов
/ 05 июня 2018

На сервере SQL я сделал пользовательский тип, подобный этому

CREATE TYPE [TowarType] AS TABLE(
    [GIDTyp] [int] NULL,
    [GIDNumer] [int] NULL,
    [Kod] [varchar](255) NULL
)

в c #, представленном моделью

public class TowaryType
{
    public int GIDTyp { get; set; }
    public int GIDNumer { get; set; }
    public string Kod { get; set; }
}

У меня также есть хранимая процедура, которая принимает этот тип какпараметр, эта процедура возвращает таблицу результатов SQL-запроса, я хочу вызвать эту хранимую процедуру с помощью Entity Framework и получить результат.Я делаю это так

   public List<ReturnModelType> GetResultFromSqlQuery<ReturnModelType>(string sqlQuery, params object[] parameters)
    {
        var result = this.Database.SqlQuery(typeof(ReturnModelType), sqlQuery, parameters);
        List<ReturnModelType> localModels = new List<ReturnModelType>();
        foreach (var o in result)
        {

            ReturnModelType m = (ReturnModelType)o;
            localModels.Add(m);
        }
        return localModels;
    }

//

 var result = _context.GetResultFromSqlQuery<ResultModel>(
                        "exec StanTowarow @Magazyny, @Towary, @Dzien", 
                        new SqlParameter("@Magazyny", magazynyParams),
                        new SqlParameter("@Towary", towaryParams),
                        new SqlParameter("@Dzien", dzien)

                    );

, но я получаю System.ArgumentException, который говорит, что для моего пользовательского типа не существует карты.

IЯ думаю, что вы должны отобразить его с помощью свободного API, но я не знаю как, кто-нибудь может указать мне правильное направление?

1 Ответ

0 голосов
/ 05 июня 2018

Мне удалось исправить мою проблему после некоторого чтения.Моя проблема заключалась в том, что были необходимы правильно сконфигурированные объекты SqlParameter, которые бы правильно передавали мои табличные значения, определенные пользователем.Я создал функцию, которая использовала список объектов из моей модели и возвратил правильно настроенный SqlParameter.

Вот мой определяемый пользователем параметр

CREATE TYPE [TowarType] AS TABLE(
    [GIDTyp] [int] NULL,
    [GIDNumer] [int] NULL,
    [Kod] [varchar](255) NULL
)

// Вот ac # модель этого параметра

 public class TowaryType
{
    public int GIDTyp { get; set; }
    public int GIDNumer { get; set; }
    public string Kod { get; set; }
}

Я создаю список своей модели и заполняю его данными

List<TowaryType> modelList = new List<TowaryType>();
//populating code here

После этого мне нужно создать SqlParameter из этого списка, поэтому я создал метод вмой applicationDbContext, который делает это для меня:

public SqlParameter GetTableValuedParameter<Model>(List<Model> valueTable, string typeName, string paramName)
        {
            if(valueTable == null || valueTable.Count == 0)
                throw new Exception("Cant be empty or null.");

            DataTable dataTable = new DataTable();

            var header = valueTable.First().GetType().GetProperties();

            foreach (var propertyInfo in header)
            {
                dataTable.Columns.Add(propertyInfo.Name);
            }

            foreach (var model in valueTable)
            {
                DataRow dataRow = dataTable.NewRow();
                var properties = model.GetType().GetProperties();
                foreach (var propertyInfo in properties)
                {
                    dataRow[propertyInfo.Name] = propertyInfo.GetValue(model);
                }

                dataTable.Rows.Add(dataRow);
            }

            var sqlParameter = new SqlParameter(paramName, SqlDbType.Structured);
            sqlParameter.Value = dataTable;
            sqlParameter.TypeName = typeName;

            return sqlParameter;
        }

После этого все, что мне нужно было сделать, это вызвать эту функцию в моих списках моделей, которые я хочу передать моей хранимой процедуре, а затем просто вызвать мою хранимую процедуру

var param1 = _context.GetTableValuedParameter(magazynyParams, "MagazynType", "@Magazyny");
var param2 = _context.GetTableValuedParameter(towaryParams, "TowarType", "@Towary");

                var result = _context.GetResultFromSqlQuery<ResultModel>(
                    "exec StanTowarow @Magazyny, @Towary, @Dzien", 
                    param1,
                    param2,
                    new SqlParameter("@Dzien", dzien)
...