2012-03-10 147 views
2

我想第一次使用實體框架,並且出現了一些問題。使用對象查詢實體框架

我有一個類AccountDataAccess:

public class AccountDataAccess 
{ 
    public IEnumerable<Account> Get(Account account) 
    { 

    } 
} 

而另一個類,賬戶

public class Account 
{ 
    string UserName { get; set; } 
    string Password { get; set; } 
    string Email { get; set; } 
    Session Session { get; set; } 
} 

當AccountDataAccess.Get()被調用時,一個或多個賬戶參數的字段可以填充(例如,只有用戶名有一個值)。 在Entity Framework中有沒有一種方法可以通過僅包含包含值的字段的搜索來查詢數據庫?

做一些google搜索,我可以看到這樣做的唯一方法後是一樣的東西

public IEnumerable<Account> Get(Account account) 
    { 
     StringBuilder queryStringBuilder = new StringBuilder("SELECT VALUE account FROM MyDatabase.Account as account WHERE "); 
     if (!String.IsNullOrWhiteSpace(account.UserName)) 
      queryStringBuilder.Append("UserName = " + account.UserName); 

     if (!String.IsNullOrWhiteSpace(account.Email)) 
      queryStringBuilder.Append("Email = " + account.Email); 
     ... 
     //continue for all fields 
     //then call database 
    }  

顯然,這是雖然做這件事的可怕方式。有任何想法嗎?

編輯

因此,對於一個完整的例子,如果我有

Account account1 = new Account() {UserName = "UserA", Email = "[email protected]"}; 
Account account2 = new Account() {UserName = "UserB"}; 

我希望爲帳戶1查詢是

var _context = new EntityModel(); 

    return _context.Where(w => w.UserName == account.UserName 
      && w.UserName == account1.UserName 
      && w.Email == account1.Email 
      ).ToList(); 

但查詢帳戶2忽略電子郵件字段,因爲它沒有填充:

var _context = new EntityModel(); 

    return _context.Where(w => w.UserName == account2.UserName 
      ).ToList(); 

所以我想我的問題是我可以動態生成的lambda表達式只包含有值的字段?

+0

只是一個說明...它是一個很好的做法,以您的界面與我...的前綴...所以你應該重命名賬戶界面爲IAccount。 – c0deNinja 2012-03-11 00:09:15

回答

1

直到添加ToList()等評估操作後才處理該查詢。所以你可以做的一件事就是建立你的查詢,類似於你在SQL中的方式。

var query = _context.Accounts.AsQueryable(); 

if (!String.IsNullOrWhiteSpace(account1.UserName)) 
    query = query.Where(a => a.UserName == account1.UserName); 

if (!String.IsNullOrWhiteSpace(account1.Email)) 
    query = query.Where(a => a.Email == account1.Email); 

你也可以用查詢語法來做同樣的事情,儘管它有點冗長。

當你完成你的查詢時,運行ToList(),ToArray()等來實際執行它並從數據庫中讀取。

+0

希望有一個更通用的方法來做到這一點,但這是迄今爲止我最好的解決方案。乾杯。 – jfc37 2012-03-11 01:58:04

0

您需要創建實體模型,並在項目中使用的實體模型,並使用LINQ查詢從像數據庫中提取的東西:

using (var _context = new EntityModel()) { 
var value = from c in _ontext 
      select person 
} 

您需要使用LINQ的實體模型後,被創建。實體會將該LINQ轉換爲SQL並執行代碼。

+0

謝謝,但有沒有辦法將where子句添加到linq表達式中,該表達式只查看填充在我的帳戶對象中的字段? – jfc37 2012-03-10 23:53:59

0

我不知道如果我明白你的問題,但在實體框架對象,其中一個查詢將是這樣的:

public class AccountDataAccess 
{ 
    public IEnumerable<Account> Get(Account account) 
    { 
     var _context = new EntityModel(); 

     return _context.Where(w => w.UserName == account.UserName 
       && w.Password == account.Password 
       && w.Email == account.Email 
       /* && other you need */ 
       ).ToList(); 
    } 
} 

此查詢將返回一個IEnumerable<Account>,但這個賬戶贏得」不是你的賬戶,而是實體框架的賬戶。

恢復您的帳戶,你需要這樣的:

public IEnumerable<Account> Get(Account account) 
    { 
     var _context = new List<Account>(); 

     return _context 
      .Where(w => w.UserName == account.UserName 
       && w.Password == account.Password 
       && w.Email == account.Email 
      ) 
      .Select(s => new Account { 
       UserName = s.UserName, 
       Password = s.Password, 
       Email = s.Email 
      }).ToList(); 
    } 

但對於這個工作,你需要申報的帳戶作爲一類不是一個接口。

+0

糟糕,已將帳戶更改爲某個班級。編輯我的問題,希望更清楚。 – jfc37 2012-03-11 00:25:08

1

簡化,實體框架的特點是將表映射到類(或反之)。說,該賬戶類將有它在你的databaase相應的表示,你應該訪問的強類型的方式,通過查詢包含在你的背景下dbsets:

//Accounts is a dbset representing the db records for the Account table 
_context.Accounts.Where(x => x.UserName == account.UserName && x.Password == account.Password && x.Email == account.Email); 

是這樣說的,一個硬編碼的SQL語句只能在EF不能完成的情況下使用(例如表格參數)。現在的問題:)

與ADO.Net不同的是,當您使用EF進行查詢時,您將返回單個或您的POCO(Account類)的列表及其所有字段,或者它們具有值或不具有值。如果獲取(帳戶帳戶)中的參數是您的查詢過濾器,則應根據您的需要選擇執行或不執行查詢。 EF基於強類型的查詢,如果您想要更動態的東西,您可以look to anonymous types,但請記住,使用內聯語句應該是最後一張牌。 An overview of Entity Framework