У меня есть приведенный ниже SQL, который прекрасно работает:
SELECT Message, CreateDate, AccountId, AlertTypeId
FROM dbo.Alerts
UNION
SELECT TOP (100) PERCENT Status, CreateDate, AccountId,
(SELECT 10 AS Expr1) AS AlertTypeId
FROM dbo.StatusUpdates
WHERE AccountId = PassedInParameter
ORDER BY CreateDate DESC
Я пытаюсь преобразовать его в LINQ, который работает не очень хорошо :) Очевидно, что здесь много чего не так - этоэто просто грубое начало.Он не учитывает вышеприведенный временный столбец или условие order by
, и неоднозначность обобщенного / возвращаемого типа - это моя попытка осмыслить два различных типа возвращаемых данных:
public List<T> GetSomething<T>(Int32 accountId)
{
List<T> result;
using (DataContext dc = _conn.GetContext())
{
IEnumerable<Alert> alerts = (from a in dc.Alerts
where a.AccountId == accountId
select a);
IEnumerable<StatusUpdate> updates = (from s in dc.StatusUpdates
where s.AccountId == accountId
select s);
IEnumerable<T> obj = alerts.Union(updates);
result = obj.ToList();
}
return result;
}
Проблемы, с которыми я сталкиваюсь,:
1) Я имею дело с двумя различными типами (Alerts и StatusUpdate) в моих выборках, и я не уверен, как их объединить (или какой тип вернуть).Я предполагаю, что это может быть решено с помощью обобщений?
2) В моем SQL у меня есть этот код: (SELECT 10 AS Expr1) AS AlertTypeId
, который добавляет значение десять к временному столбцу AlertTypeId (позволяя объединению сопоставить его с реальным Alertстолбец AlertTypeId).Как временные столбцы, подобные этому, выполняются в LINQ / как мне это сделать?
Спасибо за помощь.
РЕДАКТИРОВАТЬ --------------------------------- EDIT ------------------------------------------ EDIT
ОК, я немного дальше.Ниже то, что я имею в настоящее время.Вы заметите, что я добавил логику, чтобы вернуть обновления для отношений с друзьями.Я также сделал это универсальным методом типа IList
, учитывая, что предупреждения и обновления должны быть общими, чтобы согласовать.Я передаю StatusUpdate в вызывающем методе (далее внизу).
public IList GetUpdatesByAccountId<T>(Int32 accountId)
{
List<Friend> friends = _friendRepository.GetFriendsByAccountId(accountId);
using (DataContext dc = _conn.GetContext())
{
// Get all the account ids related to this user
var friendAccountIds =
friends.Select(friend => friend.MyFriendsAccountId).Distinct();
friendAccountIds = friendAccountIds.Concat(new[] { accountId });
var updates =
dc.StatusUpdates.Where(s => s.AccountId.HasValue && friendAccountIds.Contains(s.AccountId.Value)).Select(
s => new { Alert = (Alert)null, StatusUpdate = s});
var alerts =
dc.Alerts.Where(a => a.AccountId == accountId).Select(
a => new {Alert = a, StatusUpdate = (StatusUpdate) null});
var obj = updates.Union(alerts).Take(100);
return obj.OrderByDescending(su => su.StatusUpdate.CreateDate).ToList();
}
}
И вызывающий метод:
protected void LoadStatus()
{
repStatusUpdates.DataSource = _statusRepository
.GetUpdatesByAccountId<StatusUpdate>(_userSession.CurrentUser.AccountId);
repStatusUpdates.DataBind();
}
И вот интерфейсы к репозиториям, которые я использую дляполучить доступ к моим таблицам предупреждений и StatusUpdate через LINQ:
public interface IAlertRepository
{
List<Alert> GetAlertsByAccountId(Int32 accountId);
void SaveAlert(Alert alert);
void DeleteAlert(Alert alert);
}
public interface IStatusUpdateRepository
{
StatusUpdate GetStatusUpdateById(Int32 statusUpdateId);
List<StatusUpdate> GetStatusUpdatesByAccountId(Int32 accountId);
List<StatusUpdate> GetFriendStatusUpdatesByAccountId(Int32 accountId, Boolean addPassedInAccount);
void SaveStatusUpdate(StatusUpdate statusUpdate);
List<StatusUpdate> GetTopNStatusUpdatesByAccountId(Int32 accountId, Int32 number);
List<StatusUpdate> GetTopNFriendStatusUpdatesByAccountId(Int32 accountId, Int32 number, Boolean addPassedInAccount);
}
Текущие проблемы:
1) Когда я компилирую этот код, я получаю странную ошибку:
Невозможно привести объект типа 'System.Data.Linq.SqlClient.SqlNew' к типу 'System.Data.Linq.SqlClient.SqlValue'.
Единственное чтение, которое я могу найти, это эта ссылка хотя там нет четкого решения (по крайней мере, я могу сказать).Однако если приведенный выше код LINQ вам не подходит, возможно, все, что вы предложите, приведет к исчезновению этой ошибки.
2) Приведенный выше код все еще не учитывает эту строку из исходного SQL:
(SELECT 10 AS Expr1) AS AlertTypeId
, но это незначительно.
Еще раз спасибо за помощь.