Здесь возможна пара подходов. Я объясню оба, которые приходят на ум. Во-первых, используется отношение, уже определенное в вашей базе данных. Второе - возврат через пользовательский класс модели.
Вариант 1:
Я предполагаю, что вы создали Entity Framework Model (со связью) из своей базы данных в веб-проекте и создали DomainService для размещения этой модели. !!! Один ключ, который нужно сделать при создании модели, - это создать классы метаданных для моделей !!! (Я пропустил это первые несколько раз, и очень важно изменить поведение ваших моделей, например, здесь)
В модели метаданных вы найдете свойство ассоциации и украсите его атрибутом [Include]. Вот пример из другого проекта с WorklanDetail, где я хочу вернуть связанные Назначения:
[MetadataTypeAttribute(typeof(WorkplanDetailMetadata))]
public partial class WorkplanDetail
{
internal sealed class WorkplanDetailMetadata
{
[Include]
public EntityCollection<Assignment> Assignments { get; set; }
}
}
затем, вы можете просто сослаться на свойство в приложении Silverlight, и альта ваши данные адреса доступны.
Чтобы связать одну сущность (EntityReference, а не коллекцию), вы просто будете использовать свое свойство для доступа к под-сущности в привязке вашей таблицы данных ... Например:
Text="{Binding Path=Address.StreetName}"
Это самый простой из известных мне методов.
Вариант 2 требует создания собственного пользовательского класса (по крайней мере, вы должны иметь свойство, украшенное атрибутом [Key], чтобы облегчить передачу в / из клиента). Вот пример, который я использовал для получения информации о результатах поиска в папке:
public class FolderSearchResult
{
[Key]
public string EFOLDERID { get; set; }
public string Subject { get; set; }
public string FolderName { get; set; }
}
Ключ в том, что у свойства EFOLDERID есть атрибут [Key], который уникальным образом идентифицирует каждый элемент как PK в базе данных.
Тогда в вашем классе обслуживания вы можете вернуть такой вид:
public IEnumerable<FolderSearchResult> GetFolderResults(string search)
{
var query = from ge in this.ObjectContext.Generic_Engagement
from f in this.ObjectContext.eFolders
where ge.EFOLDERID == f.eFolderID &
f.eArchived == 0 &
f.eSubject.Contains(search) &
(from wp in this.ObjectContext.Workplans
where wp.EFOLDERID == f.eFolderID
select wp).Count() == 0 &
(from r in this.ObjectContext.Resources
where r.EFOLDERID == f.eFolderID
select r).Count() == 0
select new FolderSearchResult()
{
EFOLDERID = f.eFolderID,
FolderName = f.eFolderName,
Subject = f.eSubject
};
return query.AsEnumerable<FolderSearchResult>();
}
Пара замечаний об этом подходе:
- На мой взгляд, это работает лучше всего, когда вам не нужен доступ только для чтения. Если вы делаете обновления / вставки / удаления, используйте первый подход.
- Это хорошо помогает, когда вам нужно создать какой-то логический объект между совершенно разными источниками данных (например, идентификатор пользователя и идентификатор сотрудника из базы данных, а также отображаемое имя, местоположение сайта и т. Д. Из Active Directory).
- Обновление таким способом возможно, но вы должны проделать немного больше работы, чтобы отделить ваши элементы и правильно обновить все.
Таким образом, я бы предложил использовать первый подход, если только не происходит следующее: вам нужен логический объект, который пересекает хранилище данных (отдельные источники БД), или вам нужен быстрый доступ только для чтения (такой как привязка ItemSource для отбрасывания) список).
Выгрузка логики сортировки и фильтрации на сервер, даже за счет дополнительных объектов, загруженных в память, чтобы ваш клиент мог оставаться быстрым, приносит мне пользу. Использование локальной сортировки в CollectionViewSource или чего-то подобного может сделать то же самое, но только некоторые из них могут начать замедлять скорость вашего приложения.