2013-04-04 39 views
0

使用以下代碼;使用LINQ的EF中的計算列

using (var context = new FINSAT613Entities()) 
     { 
      gridControl1.ForceInitialize(); 



      DateTime endtime= new DateTime(2013, 03, 29, 15, 49, 54); 
      Text = "endtime:"+endtime.ToShortDateString(); 


      var query = 
       from A in context.A 
       join B in context.B on A.ID equals B.ID 
       join C in context.C on A.ID2 equals C.ID2 
       where A.endtime> endtime && A.Chk.StartsWith("320") 
       select new 
         { 
         A.ID,B.FOO,C.BAR etc... 
         }; 


      BindingSource.DataSource = query; 
      gridControl1.DataSource = BindingSource; 
     } 

我如何添加計算列呢?(倍數與b.foo a.bar例如)

使用部分類,但它沒有運氣嘗試。

public partial class A 
{ 
    public decimal Calculated 
    { 
     get { return 15; } 
    } 
} 

確切的錯誤我得到的是:

{「指定的類型成員‘已計算’不是在LINQ支撐到實體只有初始化器,實體成員和實體導航屬性都支持。。」}

+0

您的解決方案應該工作,有什麼問題你有? – 2013-04-04 08:08:34

+0

更新了我得到的錯誤... – Sin5k4 2013-04-04 08:10:59

+0

您是否在嘗試使用計算列過濾數據? – 2013-04-04 08:11:24

回答

2

您可以創建類,至極已經得到了你需要的所有領域:ID,FOO,酒吧等,並添加到它計算的字段,那麼就修改查詢:

var query = 
       from A in context.A 
       join B in context.B on A.ID equals B.ID 
       join C in context.C on A.ID2 equals C.ID2 
       where A.endtime> endtime && A.Chk.StartsWith("320") 
       select new YourNewClass 
       { 
        Foo = A.foo, 
        Bar = B.bar, 
        ... , 
        Calculated = A.foo * B.bar 
       }; 

Ë DITED:如果你有很多領域,你可以使用automapper

這裏是一個例子。比方說,你已經從你的數據庫中獲得了類User,並且你已經有了UserModel類,並且在其中添加了一個字段FullName,該字段由字段Name和Surname構成。所以你想從對象User中創建一個對象UserModel,但不是要複製所有的字段。這就是你可以這樣做的:

class Program 
    { 
     static void Main(string[] args) 
     { 
      User u = new User { Name = "My", Surname = "Name" }; 
      Mapper.CreateMap<User, UserModel>().ForMember(dest => dest.FullName, o => o.MapFrom(src => string.Format("{0} {1}", src.Name, src.Surname))); 

      UserModel um = Mapper.Map<User, UserModel>(u); 
      Console.WriteLine(um.FullName); 
     } 
    } 

    public class User 
    { 
     public string Name { get; set; } 
     public string Surname { get; set; } 
    } 

    public class UserModel 
    { 
     public string Name { get; set; } 
     public string Surname { get; set; } 
     public string FullName { get; set; } 
    } 
+0

哦,男孩我有很多領域,所以它意味着很多屬性爲班級創造,是不是有一個更簡單的方法? :) – Sin5k4 2013-04-04 08:55:57

+0

@ Sin5k4,看我的編輯 – 2013-04-04 09:23:55

+0

這篇文章[http://blog.falafel.com/calculated-field-queries-with-linq-to-entities/]顯示了一種避免處理單個屬性的簡單方法:您只需將整個類作爲屬性包含在匿名對象中即可。 – 2014-09-08 15:41:11

1

你解決了嗎?

我一直在尋找一個更好的方式我自己, 我不喜歡使用ViewModels,當我想要添加到現有模型的只有一個或兩個附加信息。

我傾向於做的是在我的模型中創建一個非映射字段,將我需要的所有信息從LINQ轉換爲臨時模型,然後在將其發送回客戶端之前在另一個循環中執行任何所需的重映射。

因此,例如;

public partial class A 
{ 
[NotMapped] 
public decimal Calculated {get;set;} 
} 

然後在我的LINQ查詢

var query = 
      from A in context.A 
      join B in context.B on A.ID equals B.ID 
      join C in context.C on A.ID2 equals C.ID2 
      where A.endtime> endtime && A.Chk.StartsWith("320") 
      select new 
        { 
        A = A, 
        B = B, 
        C = C 
        }; 
foreach(item i in query) 
    { 
     A.Calculated = A.Foo * B.Bar; 
    } 

return query 

OK,就意味着另一個循環,但至少它是唯一一個DB調用。

另一種選擇是做這一切在T-SQL,並直接發出的T-SQL(或通過存儲過程)

此鏈接介紹如何 - 作爲一個額外的獎金這種方法更快更復雜的查詢,但它總是感覺對我來說有點破綻。

http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx

0

我通過把我的數據到一個列表第一做到了這一點。這可能是可怕的(尤其是如果你有大量的結果),但它確實有效並且很容易理解。

有一個循環涉及整個列表。我不確定其他解決方案是否需要這樣做,但我現在也很難理解它們,所以我需要一些適用於我正在嘗試執行的操作,即填充DropDownList。

再次,我真的不認爲這個解決方案是理想:

比方說,我有一個實體YourEntities與表Registration

using (var context = new YourEntities()) 
{ 
    var query = from x in context.Registrations 
       select x; //Just an example, selecting everything. 
    List<Registration> MyList = query.ToList(); 
    foreach (Registration reg in MyList) //Can also be "var reg in MyList" 
    { 
     MyDropDownList.Items.Add(new ListItem(reg.LastName + ", " + reg.FirstName, reg.ID)); 
     //Or do whatever you want to each List Item 
    } 
}