2009-02-07 62 views
10

的基本問題......LinqToSQl和會員訪問不是法律上的異常類型

我有執行以下代碼的方法:

IList<Gig> gigs = GetGigs().WithArtist(artistId).ToList(); 

的GetGigs()方法從我的數據庫獲取演出通過LinqToSql ...

所以,當GetGigs()WithArtist(artistId).ToList()被執行,我得到以下異常:

Member access 'ListenTo.Shared.DO.Artist Artist' of 'ListenTo.Shared.DO.Act' not legal on type 'System.Collections.Generic.List`1[ListenTo.Shared.DO.Act] 

注意,擴展功能「WithArtist」看起來是這樣的:

public static IQueryable<Gig> WithArtist(this IQueryable<Gig> qry, Guid artistId) 
    { 
     return from gig in qry 
       where gig.Acts.Any(act => (null != act.Artist) && (act.Artist.ID == artistId)) 
       orderby gig.StartDate 
       select gig; 
    } 

如果我更換GetGigs()方法與構建演出的集合代碼(而不是通過LinqToSQL數據庫的方法)我沒有得到例外。

所以我相當肯定,問題是我LinqToSQl代碼,而不是對象結構。

不過,我不知道爲什麼LinqToSQl版本心不是工作,所以我下面包括了所有相關的代碼。任何幫助將非常感激地收到!

的LinqToSQL代碼....

public IQueryable<ListenTo.Shared.DO.Gig> GetGigs() 
    { 
     return from g in DBContext.Gigs 
       let acts = GetActs(g.ID) 
       join venue in DBContext.Venues on g.VenueID equals venue.ID 
       select new ListenTo.Shared.DO.Gig 
       { 
        ID = g.ID, 
        Name = g.Name, 
        Acts = new List<ListenTo.Shared.DO.Act>(acts), 
        Description = g.Description, 
        StartDate = g.Date, 
        EndDate  = g.EndDate, 
        IsDeleted = g.IsDeleted, 
        Created  = g.Created, 
        TicketPrice = g.TicketPrice, 
        Venue  = new ListenTo.Shared.DO.Venue { 
            ID = venue.ID, 
            Name = venue.Name, 
            Address = venue.Address, 
            Telephone = venue.Telephone, 
            URL = venue.Website 
        } 

       }; 
    } 



    IQueryable<ListenTo.Shared.DO.Act> GetActs() 
    { 
     return from a in DBContext.Acts 

       join artist in DBContext.Artists on a.ArtistID equals artist.ID into art 
       from artist in art.DefaultIfEmpty() 

       select new ListenTo.Shared.DO.Act 
       { 
        ID = a.ID, 
        Name = a.Name, 
        Artist = artist == null ? null : new Shared.DO.Artist 
        { 
         ID = artist.ID, 
         Name = artist.Name 
        }, 
        GigId = a.GigID 

       }; 
    } 

    IQueryable<ListenTo.Shared.DO.Act> GetActs(Guid gigId) 
    { 
     return GetActs().WithGigID(gigId); 
    } 

我已經包含了該法案,藝術家和千兆下面的代碼對象:

public class Gig : BaseDO 
{ 

    #region Accessors 

    public Venue Venue 
    { 
     get; 
     set; 
    } 

    public System.Nullable<DateTime> EndDate 
    { 
     get; 
     set; 
    } 

    public DateTime StartDate 
    { 
     get; 
     set; 
    } 

    public string Name 
    { 
     get; 
     set; 
    } 

    public string Description 
    { 
     get; 
     set; 
    } 

    public string TicketPrice 
    { 
     get; 
     set; 
    } 

    /// <summary> 
    /// The Act object does not exist outside the context of the Gig, therefore, 
    /// the full act object is loaded here. 
    /// </summary> 
    public IList<Act> Acts 
    { 
     get; 
     set; 
    } 

    #endregion 
} 

public class Act : BaseDO 
{ 
    public Guid GigId { get; set; } 
    public string Name { get; set; } 
    public Artist Artist { get; set; } 
} 

public class Artist : BaseDO 
{ 
    public string Name { get; set; } 
    public string Profile { get; set; } 
    public DateTime Formed { get; set; } 
    public Style Style { get; set; } 
    public Town Town { get; set; } 
    public string OfficalWebsiteURL { get; set; } 
    public string ProfileAddress { get; set; } 
    public string Email { get; set; } 
    public ImageMetaData ProfileImage { get; set; } 

} 

public class BaseDO: IDO 
{ 
    #region Properties 

    private Guid _id; 

    #endregion 

    #region IDO Members 

    public Guid ID 
    { 
     get 
     { 
      return this._id; 
     } 
     set 
     { 
      this._id = value; 
     } 
    } 




} 

}

+0

我遇到了這個相同的錯誤,在我的情況下,它似乎與我的WHERE子句中使用相關的子查詢有關。如果我找到任何信息,我會給你一個更新。 – jpierson 2010-10-25 20:00:14

回答

1

我沒有看到在你的類的任何指示的LINQ to SQL如何是爲了鍛鍊身體哪一列是等

w ^您是否期望在.NET中執行WithArtist方法,或將其轉換爲SQL?如果您希望將其轉換爲SQL,則需要使用適當的LINQ to SQL屬性來裝飾Gig類(或者以其他方式配置數據上下文)。如果您希望以代碼形式執行,只需將第一個參數類型從IQueryable<Gig>更改爲IEnumerable<Gig>即可。

+0

有自動生成的LinqToSQl gig類。上面定義的gig類是模式驅動的對象,我正在將LinqToSQl數據適配到... – iasksillyquestions 2009-02-07 18:10:34

+0

那麼,您從GetGigs()返回的那種GigQ類型,LINQ to SQL知道與否? – 2009-02-07 18:23:23

+0

@Jon:我知道你很忙(現在這個問題已經很老了),但是有沒有機會用一些代碼來詳細說明你的答案......強調要將*轉換爲SQL *,角度。我在這裏遇到了完全相同的問題。我正在使用Repository模式(例如GetActs())+管道和過濾器(例如,使用Artist()),並且我的存儲庫不處理其他* children *屬性(例如,Gigs是父級,Acts屬性是child) ,所以我試圖操縱查詢(例如WithActs())來動態地返回一個關聯的孩子,如果消費者編碼的話。這個問題正在導致我死亡:( – 2009-11-20 02:22:06

4

我認爲這個問題是在GetGigs的「讓」語句。使用'let'意味着你定義了一個最終查詢的一部分,與主集合分開提取。問題是如果它不是標量,那麼'let'將導致嵌套查詢。嵌套查詢並不是真正的Linq,因爲它們也被延遲執行。在您的查詢中,將嵌套查詢的結果放入主集的投影中,返回該集,然後再添加linq運算符。

當發生這種情況時,嵌套查詢被深埋在將要執行的查詢中,並且這導致嵌套查詢不在要執行的查詢的外部投影中並因此必須被合併的情況進入SQL查詢運行到數據庫。這是不可行的,因爲它是嵌套在主SQL查詢中的投影中的嵌套查詢,並且SQL沒有「投影中的嵌套查詢」這樣的概念,因爲您無法在投影中獲取一組元素SQL,只有標量。

5

我有同樣的問題,對我來說似乎做的伎倆是分離出一個內聯靜態方法調用,返回IQueryable <>以便我將這個延遲查詢存儲到一個變量並引用它。

我認爲這是Linq to SQL中的一個錯誤,但至少有一個合理的解決方法。我還沒有測試過,但我的假設是,只有在查詢表達式中引用不同類的靜態方法時,纔會出現此問題,而不管該函數的返回類型是否爲IQueryable <>。所以,也許這是一個掌握問題根源的方法。就像我說的,我還沒有能夠證實這一點,但它可能是值得調查的。

更新:爲了以防萬一解決方案不明確,我想指出它在原始帖子的例子的上下文中。

public IQueryable<ListenTo.Shared.DO.Gig> GetGigs() 
{ 
    var acts = GetActs(g.ID); // Don't worry this call is deferred 

    return from g in DBContext.Gigs 
      join venue in DBContext.Venues on g.VenueID equals venue.ID 
      select new ListenTo.Shared.DO.Gig 
      { 
       ID = g.ID, 
       Name = g.Name, 
       Acts = new List<ListenTo.Shared.DO.Act>(acts), 
       Description = g.Description, 
       StartDate = g.Date, 
       EndDate  = g.EndDate, 
       IsDeleted = g.IsDeleted, 
       Created  = g.Created, 
       TicketPrice = g.TicketPrice, 
       Venue  = new ListenTo.Shared.DO.Venue { 
           ID = venue.ID, 
           Name = venue.Name, 
           Address = venue.Address, 
           Telephone = venue.Telephone, 
           URL = venue.Website 
       } 

      }; 
} 

注意的是,雖然這應該糾正當前的問題看起來也似乎是在遞延行爲查詢另一個問題,我猜會導致單獨的查詢投影的每個元素都被訪問到發行到外部投影中的每行數據庫。