Как манипулировать значениями в запросе LINQ без ошибки «Явная конструкция типа сущности ### в запросе не допускается при попытке изменить значение» - PullRequest
0 голосов
/ 10 марта 2010

Можно ли изменить значение поля внутри запроса выбора LINQ для использования в приложении ASP.NET MVC?

Например, если запрос возвращает поле со значением «foo», я хочу, чтобы его вывод был «bar».

По сути, я хочу, чтобы LINQ создал этот оператор TSQL:

CREATE PROCEDURE GetSpecialCaseOfMyObject (
     @param varchar(10)
     ) AS

SELECT
     REPLACE( FieldA, 'foo', @param ) [FieldA]
     FieldB,
     FieldC
FROM
     MyTable
WHERE
     FieldA = @param

Я зашел так далеко, и он строит, но ...

public IQueryable<MyObject> GetSpecialCaseOfMyObject (string myParam)
{
        var result = from o in Context.MyObject
                     where o.FieldA = myParam
                     select new MyObject
                        {
                                FieldA = o.FieldA.Replace("foo", myParam),
                                FieldB = o.FieldB,
                                FieldC = o.FieldC
                        };

        return result;
}

... когда я пытаюсь запустить View, чтобы вернуть данные из него, я получаю желтый экран смерти:

Явное построение типа сущности Model.DataAccess.MyObject в запросе не допускается.

Я пытался использовать анонимный тип, но потом не могу привести его обратно к MyObject.

Возможно ли то, что я хочу сделать, не прыгая через все виды обручей?

Ответы [ 2 ]

0 голосов
/ 11 марта 2010

Это было бы действительно легко, если бы у вас была модель предметной области или даже модель представления. Вы можете использовать инструмент, такой как AutoMapper , чтобы справиться с большей частью тяжелой работы. Все, что вам нужно сделать, это создать класс, похожий на модель сущности:

public class MyViewObject
{
    public MyViewObject(string fieldA, string fieldB, string fieldC)
    {
        this.FieldA = fieldA;
        this.FieldB = fieldB;
        this.FieldC = fieldC;
    }

    public string FieldA { get; set; }
    public string FieldB { get; set; }
    public string FieldC { get; set; }
}

И затем сопоставьте его (я показываю здесь ручное отображение, но, как я уже сказал, вы можете автоматизировать многое из этого с помощью инструмента для автоматического сопоставления):

public IEnumerable<MyViewObject> GetViewObjects(string arg)
{
    var dataObjects = GetMyObjects(arg);
    return dataObjects.Select(o => TransformMyObject(o, "bar"));
}

public MyViewObject TransformMyObject(MyObject o, string fooReplacement)
{
    return new MyViewObject(o.FieldA, o.FieldB,
        o.FieldC.Replace("foo", fooReplacement);
}

Это действительно не так много работы, и это сделает намного проще для поддержки будущих изменений в логике представления. Также нормально иметь некоторую эту логику в представлении, если это действительно простое форматирование, но я предпочитаю сохранять представления настолько тупыми, насколько это возможно, так как модели представления содержат в основном (или полностью) строковые свойства.

Может показаться, что вы «прыгаете через обручи» сейчас, но как только у вас будет отдельный домен и / или модель представления, вы будете удивляться, как вы обходились без него. Когда в вашем приложении отсутствует целый слой, вы начинаете сталкиваться с этими странными проблемами с утечкой абстракции.

0 голосов
/ 11 марта 2010

Я бы не стал изменять логику запроса. Ответственность за форматирование вывода лежит на представлении. Поэтому оставьте запрос как есть:

public IQueryable<MyObject> GetMyObject (string myParam)
{
    return from o in Context.MyObject
           where o.FieldA = myParam
           select o;
}

и в вашем представлении, если необходимо:

<div><%= Html.Encode(Model.FieldA.Replace("foo", "bar")) %></div>

или даже лучше написать помощник:

public static string FormatFieldA(this MyObject myObject)
{
    return myObject.FieldA.Replace("foo", "bar");
}

, который можно использовать как:

<div><%= Html.Encode(Model.FormatFieldA()) %></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...