![](/img/trans.png)
[英]Is there any difference in performance between Database.SqlQuery and EF 6.1?
[英]EF 6.1 Database.SqlQuery projection into complex type (many-to-many relationship)
在Entity Framework 6.1中是否可以使用Database.SqlQuery命令執行包含多對多關系的查詢,並將其映射回DTO(使用中間DTO-我知道這不可能一次完成)? 以及該動作將如何執行?
此示例是我當前面臨的問題的極其簡化的版本 。 我只是對Database.SqlQuery可以(不能)完成什么感興趣。
我知道我可以使用導航屬性(使用Linq),但是我正在研究更復雜的查詢的性能。 這只是我要達到的目標的非常簡化的版本。
數據庫
DTO
public class EventDto{
public int EventId {get;set;}
public string Name {get;set;}
public string Slug {get;set;}
public List<ArtistDto> Headliners {get;set;}
}
public class ArtistDto{
public int ArtistId {get;set;}
public string Name {get;set;}
public string Bio {get;set;}
}
臨時DTO
public class EventWithHeadlinersDto{
public int EventId {get;set;}
public string Name {get;set;}
public string Slug {get;set;}
public int ArtistId {get;set;}
public string Name {get;set;}
public string Bio {get;set;}
}
碼
return Context.Database.SqlQuery<EventWithHeadlinersDto>(@"
SELECT * FROM [Events] E
LEFT JOIN [Headliners] H ON E.EventId = H.EventId
LEFT JOIN [Artists] A ON H.ArtistId = A.ArtistId
WHERE E.eventid = @eventId",
new SqlParameter("eventId", eventId))
.ToListAsync();
需要一些編碼(基本上是復制EF查詢實現過程),但是可行。
首先,應將臨時DTO修改為包括所有必填字段,並考慮到left joins
(在需要時使用nullable
類型):
public class EventWithHeadlinersDto
{
// Event Info
public int EventId { get; set; }
public string EventName { get; set; }
public string EventSlug { get; set; }
// Artist Info
public int? ArtistId { get; set; }
public string ArtistName { get; set; }
public string ArtistBio { get; set; }
}
然后,您應確保SQL SELECT
包括所有必要的列,並在必要時使用別名以匹配DTO屬性名稱:
var sql = @"
SELECT
E.EventId, E.Name EventName, E.Slug EventSlug,
A.ArtistId, A.Name ArtistName, A.Bio ArtistBio
FROM [Events] E
LEFT JOIN [Headliners] H ON E.EventId = H.EventId
LEFT JOIN [Artists] A ON H.ArtistId = A.ArtistId
WHERE E.EventId = @eventId";
然后執行sql查詢並獲得設置的DTO結果:
var dataSet = await query.ToListAsync();
最后將其轉換為所需的格式:
var eventMap = new Dictionary<int, EventDto>();
var artistMap = new Dictionary<int, ArtistDto>();
foreach (var entry in dataSet)
{
EventDto @event;
if (!eventMap.TryGetValue(entry.EventId, out @event))
{
@event = new EventDto
{
EventId = entry.EventId,
Name = entry.EventName,
Slug = entry.EventSlug,
Headliners = new List<ArtistDto>()
};
eventMap.Add(@event.EventId, @event);
}
if (entry.ArtistId != null)
{
ArtistDto artist;
if (!artistMap.TryGetValue(entry.ArtistId.Value, out artist))
{
artist = new ArtistDto
{
ArtistId = entry.ArtistId.Value,
Name = entry.ArtistName,
Bio = entry.ArtistBio,
};
artistMap.Add(artist.ArtistId, artist);
}
@event.Headliners.Add(artist);
}
}
var resultSet = eventMap.Values.ToList();
當然,在示例情況下,結果集將僅包含0或1個項目,但是以上內容適用於任何應用的過濾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.