Мой код для подключения sql с использованием linq:
var query1 = from u in dc.Usage_Computers
where u.DomainUser == s3
select u; // selects all feilds from table
GridView1.DataSource = query1;
GridView1.DataBind();
У меня есть поле под названием «Операция» в таблице «Пользователь домена», которое имеет такие значения, как «1, 2, 3». Когда я заполняю эти значения в сетке данных, я хотел преобразовать их в значимые значения, например, если значение Operation равно 1, то отображать в сетке данных как «вход в систему», если 2, то «выход из системы» и т. д.
Как мне присвоить им значения после извлечения из базы данных?





Я сделал нечто подобное, используя TemplateFields. Использование ASP: метка, привязанная к свойству, и добавление обработчика событий OnPreRender для элемента управления. В обработчике событий для элемента управления я перевожу текст на основе его текущего значения и устанавливаю новое значение:
protected void label_OnPreRender( object sender, EventArgs e )
{
Label l = (Label)sender;
switch (l.Text) {
case "1":
l.Text = "Logon";
break;
...
default:
break;
}
}
Если форма находится в режиме редактирования, вам нужно будет обработать ее по-другому. Вам также, вероятно, потребуется добавить обработчики для вставки и обновления в элемент управления View, который вы используете для преобразования данных, предоставленных страницей, в ее представление базы данных.
Используйте поле шаблона в вашей сетке:
<asp:GridView ID = "gvDomain" runat = "server" OnRowDataBound = "gvDomain_RowDataBound">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
Operation
</HeaderTemplate>
<ItemTemplate>
<asp:Label id = "lblLogon" runat = "server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Затем используйте событие RowDataBound gridviews, чтобы обнаружить метку и назначить ее текст:
Protected Sub gvDomain_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvStates.RowDataBound
Dim lblLogon As Label = DirectCast(e.Row.FindControl("lblLogon"), Label)
Dim drv As DataRowView = DirectCast(e.Row.DataItem, DataRowView)
If lblLogon IsNot Nothing Then
Select Case drv("Operation").ToString()
Case "1"
lblLogon.Text = "Logon"
Break
Case "2"
lblLogon.Text = "Logoff"
Break
//etc...
End Select
End If
End Sub
static Func<int?, string> MapSqlIntToArbitraryLabel = (i =>
{
// for performance, abstract this reference
// dictionary out to a static property
Dictionary<int, string> labels = new Dictionary<int, string>();
labels.Add(1, "logon");
labels.Add(2, "logoff");
labels.Add(...);
if (i == null) throw new ArgumentNullException();
if (i < 1 || i > labels.Count) throw new ArgumentOutOfRangeException();
return labels.Where(x => x.Key == i.Value)
.Select(x.Value)
.Single();
}
этот оператор возврата также может быть выражен как:
return (from kvp in labels
where kvp.Key == i.Value
select kvp.Value).Single();
Затем вы можете вызвать эту функцию из своего запроса linq следующим образом:
var query1 = from u in dc.Usage_Computers
where u.DomainUser == s3
select {
Operation = MapSqlIntToArbitraryLabel(u.Operation)
// add other properties to this anonymous type as needed
};
Я пробовал все предложенные методы обмануть Linq2Sql для запуска моего кода, и этот метод - единственный, который я нашел, который позволяет мне запускать код как часть проекции отложенного выполнения.
Хотя в целом я согласен с подходом (+1), думаю, это немного излишне. Может быть достаточно простого словаря (и обеспечить лучшую производительность). И инициализировать следует только один раз. Единственное, что нужно сделать, это сделать метод перевода методом расширения объекта.
Методы расширения объекта были моей первой попыткой, но я обнаружил, что этот подход хорошо обобщается, т. Е. Из MapSqlIntToArbitraryLabel () вы можете вызвать метод, который не распознается Linq2Sql, и он, похоже, работает, не задыхаясь от «нет перевода на sql "проблема.
Этот метод не кажется особенно применимым к вашей проблеме, но вот он, в любом случае.
Вы можете создать оператор case SQL в LinqToSql с помощью оператора C# ? :.
var query1 =
from u in dc.Usage_Computers
where u.DomainUser == s3
select new {usage = u,
operation =
u.DomainUser.Operation == 1 ? "login" :
u.DomainUser.Operation == 2 ? "logoff" :
"something else"
};
Я никогда не узнаю, почему люди хотят, чтобы база данных преобразовывала int в строки меток. Похоже на работу для веб-сервера.
пока решение отвечает на вопрос, я думаю, что такое разбрасывание логики преобразования - плохая практика. Такая логика преобразования должна быть централизована в повторно используемый класс.
Дэвид, когда предоставляется возможность выполнить такое простое преобразование на веб-сервере или в базе данных, вы можете определить, какой движок уже имеет наименьшую нагрузку, и выполнить преобразование там. Часто на сервере базы данных доступно больше ЦП.
Дело не в доступности ЦП. Вся эта логика должна быть передана в базу данных с кучей параметров. Затем база данных должна отправить обратно строки, когда она могла бы отправить обратно ints (меньший размер сети запроса и ответа). Это похоже на прикрепление лезвий к спицам велосипеда и катание по траве, чтобы косить лужайку. Инструмент неподходящий для работы, даже если он работает.
возможный дубликат оператор linq case