2017-08-15 31 views
1

我一直在以代碼優先的方式在實體框架上遇到以下問題。EF代碼優先 - IQueryable在特定的小數屬性上有乘法

我有一個小數的實體類,我有一個乘數小數參數。

我想構建一個查詢(但不能調用它),它返回實體,但Bar屬性需要與我的參數相乘。

從編碼側:

public class Foo 
{ 
    public Guid Id { get; set; } 
    public Decimal Bar { get; set; } 
} 

// this simple stuff returns the entities after some filterings. 
Context.Set<Foo>().Where(x => querying on many props).ToList(); 

這種方法類同什麼我想要實現:

public IQueryable<Foo> GetFooQuery(.. Many properties used to the query .. , Decimal Multiplier) 
{ 
    var IQueryablePart = Context.Set<Foo>().Where(querying with the parameters); 

    /* ... and what to do here? ... */ 
    /* IQueryablePart = IQueryablePart.Select(x => new { 
      Bar = Bar * Multiplier <-- this is okay 
     }); */ 
    // but how to retrieve the other columns without listing them one by one, and how to return the data as IQueryable<Foo> ? 

    return IQueryablePart; 
} 

我想通過以下方式來使用此方法:

IQueryable<Foo> FullQuery = null; 

for(some loop, may be 10 or 1000 iterations, it depends) { 
    var Part = GetFooQuery(/* .. query params ..*/, 2); 

    if(MyFullQuery == null) 
     FullQuery = Part; 
    else 
     FullQuery.Union(Part); 
} 

// and in the end, do the db call once: 
var Result = FullQuery.ToList(); 

在SQL中,我會這樣處理它:

SELECT 
    Id, 
    Bar * @MyValue as Bar, 
    # and all other columns 
FROM 
    Foo 
WHERE 
    (param queries 1) OR 
    (param queries 2) OR 
    --- 
    (param queries N) 

我的問題是:如何通過IQueryable和EF來做到這一點?最重要的是,我只需要一次調用db。

我認爲它可能是某些查詢的建築的東西,但我不熟悉它,但任何幫助將是非常讚賞。

+1

如果兩個'Bar'和'myvalue的:

最後,你可以通過執行單一的最終SQL查詢,切換到LINQ到對象和轉換FooBarFoo這樣兌現的結果作爲Foo sequennce '是相同的表(即實體)的一部分,那麼合乎邏輯的解決辦法是在你的代碼,而不是一個自動屬性檢索。 – silkfire

+0

不幸的是,他們不是。乘數由代碼計算。 –

+0

你從哪裏得到@MyValue? – silkfire

回答

0

EF6不支持將投影(select)映射爲映射爲實體的類。因此,你唯一的選擇是投射到一些匿名或特殊的班級。對於您的情況,我看最簡單的就是這樣的一類:

public class FooBar 
{ 
    public Foo Foo { get; set; } 
    public decimal Bar { get; set; } 
} 

然後單查詢方法可能是這樣的:

public IQueryable<FooBar> GetFooQuery(.. Many properties used to the query .. , decimal multiplier) 
{ 
    return Context.Set<Foo>() 
     .Where(querying with the parameters) 
     .Select(foo => new FooBar 
     { 
      Foo = foo, 
      Bar = foo.Bar * multiplier 
     }); 
} 

現在你可以建立完整的查詢:

IQueryable<FooBar> fullQuery = null; 

for (some loop, may be 10 or 1000 iterations, it depends) 
{ 
    var subQuery = GetFooQuery(/* .. query params ..*/, 2); 

    fullQuery = fullQuery == null ? subquery : fullQuery.Union(subQuery); 
} 

請注意,如果您使用不同的乘數(否則整個過程沒有意義),你最好使用LINQ Concat方法(這相當於SQL UNION ALL),而TH恩Union(這相當於SQL UNION)。

var result = fullQuery. 
    .AsEnumerable() // db query ends here 
    .Select(fooBar => 
    { 
     fooBar.Foo.Bar = fooBar.Bar; 
     return fooBar.Foo; 
    }) 
    .ToList(); 
+0

乘法器在不同迭代之間變化,所以我的目標是在數據從數據庫中拉出之後,讓db在代碼中計算乘法而不是「me」。 –

+0

這個傳輸類的解決方案在db中進行了計算,但是,我仍然需要在調用完整查詢後選擇元素,但比使用該方法後進行後期計算更優​​雅,而且我仍然有「額外的工作「,無論如何都要對查詢進行拼接。感謝您的解決方案。 –