2

我一直在這個背後摸不着頭腦,但仍然無法弄清楚可能會導致這種情況。Linq to SQL使用存儲庫模式:對象沒有支持轉換到SQL

我有一個複合存儲庫對象引用兩個其他存儲庫。我想在我的LINQ查詢中實例化Model類型(請參閱第一個代碼片段)。

public class SqlCommunityRepository : ICommunityRepository {

private WebDataContext _ctx; 
    private IMarketRepository _marketRepository; 
    private IStateRepository _stateRepository; 

    public SqlCommunityRepository(WebDataContext ctx, IStateRepository stateRepository, IMarketRepository marketRepository) 
    { 
     _ctx = ctx; 
     _stateRepository = stateRepository; 
     _marketRepository = marketRepository; 
    } 

    public IQueryable<Model.Community> Communities 
    { 
     get 
     { 
      return (from comm in _ctx.Communities 
        select new Model.Community 
        { 
         CommunityId = comm.CommunityId, 
         CommunityName = comm.CommunityName, 
         City = comm.City, 
         PostalCode = comm.PostalCode, 
         Market = _marketRepository.GetMarket(comm.MarketId), 
         State = _stateRepository.GetState(comm.State) 
        } 
        ); 
     } 
    } 
} 

說我傳遞模樣的資源庫對象本

public class SqlStateRepository : IStateRepository {

private WebDataContext _ctx;

public SqlStateRepository(WebDataContext ctx) { _ctx = ctx; }

public IQueryable<Model.State> States 
    { 
     get 
     { 
      return from state in _ctx.States 
        select new Model.State() 
        { 
         StateId = state.StateId, 
         StateName = state.StateName 
        }; 
     } 
    } 

    public Model.State GetState(string stateName) 
    { 
     var s = (from state in States 
       where state.StateName.ToLower() == stateName 
       select state).FirstOrDefault(); 

     return new Model.State() 
     { 
      StateId = s.StateId, 
      StateName = s.StateName 
     }; 
    } 

public class SqlMarketRepository : IMarketRepository {

private WebDataContext _ctx;

public SqlMarketRepository(WebDataContext ctx) 
    { 
     _ctx = ctx; 
    } 

    public IQueryable<Model.Market> Markets 
    { 
     get 
     { 
      return from market in _ctx.Markets 
        select new Model.Market() 
           { 
            MarketId = market.MarketId, 
            MarketName = market.MarketName, 
            StateId = market.StateId 
           }; 
     } 
    } 

    public Model.Market GetMarket(int marketId) 
    { 
     return (from market in Markets 
       where market.MarketId == marketId 
       select market).FirstOrDefault(); 
    } 
} 

這是我如何接線這一切:

 WebDataContext ctx = new WebDataContext(); 
     IMarketRepository mr = new SqlMarketRepository(ctx); 
     IStateRepository sr = new SqlStateRepository(ctx); 
     ICommunityRepository cr = new SqlCommunityRepository(ctx, sr, mr); 
     int commCount = cr.Communities.Count(); 

上面代碼片段的最後一行是失敗的地方。當我通過實例化(new Model.Community)進行調試時,它永遠不會進入任何其他存儲庫方法。這三個對象背後的底層表之間沒有關係。這是否會成爲LINQ to SQL無法正確構建表達式樹的原因?

回答

1

這些是非水合查詢,而不是完全水合的集合。

社區查詢與其他兩個查詢不同,因爲在對象水合時調用方法。這些方法調用不能轉換爲SQL。


通常這不是問題。例如:如果你說Communities.ToList(),它將起作用,並且方法將在對象水合時被調用。

如果修改查詢,以便的對象不水合,例如:當你說Communities.Count(),LINQ to SQL中嘗試發送方法調用到數據庫中,並拋出,因爲它不能。即使這些方法調用最終不會影響結果計數,它也會這樣做。


的簡單的解決辦法(如果你真正希望完全水化的集合)是添加ToList到社區查詢,補水吧。

+0

這樣做。它不會觸發查詢,直到你調用IQueryable上的方法? – Praveen 2010-08-03 18:30:51

+1

大多數Linq方法都是延遲的 - 直到枚舉結果纔會評估查詢。 foreach和ToList都是枚舉查詢的手段。 – 2010-08-03 23:13:19

0

嘗試增加看起來像這樣的另一個倉庫方法:

public int CommunitiesCount() 
{ 
    get { return _ctx.Communities.Count(); } 
} 

這將允許您無需將整個對象樹暴露給用戶,這是我認爲你正在試圖做的返回計數無論如何。你可能已經猜到了,我懷疑你所稱的匿名類型是錯誤的(它們並不是真正的匿名類型,它們是實際的對象,你顯然是爲了隱藏某些東西來自最終用戶的字段)。

+0

我不確定Count()方法本身是否是罪魁禍首。當我做cr.Communities時,我期待着一個完全水合的IQueryable集合。 mr.Markets.Count()和sr.States.Count()返回預期的結果。 – Praveen 2010-08-03 00:09:28

+0

count()的這個特殊的演繹是否奏效? – 2010-08-03 01:03:19

+0

是的,_ctx.Communities.Count()給我正確的計數。但是,我正在尋找communityRepository.Communities,一個IQueryable 列表。 – Praveen 2010-08-03 15:29:16