2012-03-10 114 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