Недавно я создал Boundary, библиотеку CSS + JS для решения таких проблем. Граница создает элементы, которые полностью отделены от CSS существующей веб-страницы.
Возьмите создание диалогового окна, например. После установки Boundary вы можете сделать это в своем скрипте содержимого
var dialog = Boundary.createBox("yourDialogID", "yourDialogClassName");
Boundary.loadBoxCSS("#yourDialogID", "style-for-elems-in-dialog.css");
Boundary.appendToBox(
"#yourDialogID",
""
);
Boundary.find("#submit_button").click(function() {
// some js after button is clicked.
});
Элементы в #yourDialogID не будут затронуты существующей веб-страницей. И функция find () возвращает регулярный элемент DOM jQuery, чтобы вы могли делать с ним все, что хотите.
Надеюсь, это поможет. Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.
Сущности могут создаваться вне запросов и вставляться в хранилище данных с использованием DataContext. Затем вы можете получить их с помощью запросов. Однако вы не можете создавать объекты как часть запроса.
Я построю анонимный тип, использую IEnumerable (который сохраняет отложенное выполнение), а затем повторно воссоздает объект datacontext. Оба Employee и Manager являются объектами datacontext:
var q = dc.Employees.Where(p => p.IsManager == 1)
.Select(p => new { Id = p.Id, Name = p.Name })
.AsEnumerable()
.Select(item => new Manager() { Id = item.Id, Name = item.Name });
Я нашел еще одно решение этой проблемы, которое позволяет сохранить результат как IQueryale, поэтому он фактически не выполняет запрос до тех пор, пока вы его не выполнили (например, с методом ToList ()).
Итак, linq не позволяет создавать объект как часть запроса? Вы можете перенести эту задачу в базу данных и создать функцию, которая будет захватывать нужные вам данные. После импорта функции в контекст данных вам просто нужно установить тип результата на тот, который вы хотите.
Я узнал об этом, когда мне пришлось написать фрагмент кода, который создайте IQueryable<T>
, в котором элементы фактически не существуют в таблице, содержащей T.
Я просто столкнулся с той же проблемой.
Я нашел очень легкое решение.
var a = att as Attachment;
Func<Culture, AttachmentCulture> make =
c => new AttachmentCulture { Culture = c };
var culs = from c in dc.Cultures
let ac = c.AttachmentCultures.SingleOrDefault(
x => x.Attachment == a)
select ac == null ? make(c) : ac;
return culs;
Я обнаружил, что если вы выполняете .ToList () в запросе, прежде чем пытаться конструировать новые объекты, он работает
Вот еще одно обходное решение:
internal class OrderView : Order { }
var query = from o in db.Order
select new OrderView // instead of Order
{
OrderID = o.OrderID,
OrderDate = o.OrderDate,
// etc.
};
return query.Cast<Order>().ToList(); // or .FirstOrDefault()
Примечание: я не тестировал, или нет; он работает для извлечения данных, которые мне нужны.
В книге «70-515 Разработка веб-приложений с Microsoft .NET Framework 4 - Учебный комплект для самостоятельного обучения» на стр. 638 приведен следующий пример для вывода результатов строго типизированному объекту:
IEnumerable<User> users = from emp in employees where emp.ID !=0
select new User
{
Name = emp.First + " " + emp.Last,
EmployeeId = emp.ID
}
Совет Марк Пекс, похоже, противоречит этой книге - однако для меня этот пример все еще отображает вышеупомянутую ошибку, оставляя меня несколько смущенным. Связано ли это с различиями в версии? Любые предложения приветствуются.
Я считаю, что это ограничение очень раздражает и противоречит общей тенденции не использовать SELECT * в запросах.
Тем не менее с анонимными типами c # существует обходное решение, путем извлечения объектов в анонимного типа, а затем скопируйте его в правильный тип.
Например:
var q = from emp in employees where emp.ID !=0
select new {Name = emp.First + " " + emp.Last, EmployeeId = emp.ID }
var r = q.ToList();
List<User> users = new List<User>(r.Select(new User
{
Name = r.Name,
EmployeeId = r.EmployeeId
}));
И в случае, когда мы имеем дело с одним значением (как в ситуации, описанной в вопросе), это еще проще, и нам просто нужно чтобы скопировать непосредственно значения:
var q = from emp in employees where emp.ID !=0
select new { Name = emp.First + " " + emp.Last, EmployeeId = emp.ID }
var r = q.FirstOrDefault();
User user = new User { Name = r.Name, EmployeeId = r.ID };
Если имя свойства соответствует столбцам базы данных, мы можем сделать это еще проще в запросе, выполнив select
var q = from emp in employees where emp.ID !=0
select new { emp.First, emp.Last, emp.ID }
One может пойти вперед и написать выражение лямбда, которое может автоматически копироваться на основе имени свойства, без необходимости явно указывать значения.
ToList
в вашем решении поместит результаты в память, что, вероятно, нежелательно для больших наборов данных.
– Protector one
7 August 2017 в 15:06