使用对象查询实体框架

时间:2012-03-10 22:21:52

标签: c# entity-framework

我第一次尝试使用实体框架,并且有点不稳定。

我有一个类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()时,可以填充一个或多个帐户参数字段(例如,只有UserName具有值)。 在Entity Framework中是否有一种方法可以使用仅包含值的字段来搜索数据库?

在做了一些谷歌搜索后,我能看到的唯一方法是

    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 = "UserA@email.com"};
Account account2 = new Account() {UserName = "UserB"};

我希望account1的查询为

    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表达式只包含具有值的字段?

4 个答案:

答案 0 :(得分: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()等,以实际执行它并从数据库中读取。

答案 1 :(得分:1)

简化,实体框架的特点是将表映射到类(或反之亦然)。说,Account类将在您的数据库中具有它的相应表示,您应该通过查询上下文中包含的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);

这就是说,只有在不能用EF(例如表参数)完成某些事情时才应该使用硬编码的sql语句。现在的问题是:)

与ADO.Net不同,当您使用EF查询时,您将获得POCO(Account类)的单个或列表及其所有字段,或者是否有值。如果获取(帐户帐户)中的参数是您的查询过滤器,则应根据需要选择是否执行查询。 EF基于强类型查询,如果你想要更动态的东西,你可以look to anonymous types但请记住,内联语句的使用应该是最后一张牌。 An overview of Entity Framework

答案 2 :(得分:0)

您需要创建实体模型并在项目中使用实体模型,并使用LINQ查询从数据库中提取内容,如:

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

创建实体模型后,您需要使用Linq。实体会将LINQ转换为SQL并执行代码。

答案 3 :(得分:0)

我不知道我是否理解你的问题,但实体框架对象中的WHERE查询将是这样的:

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();
    }

但要使其工作,您需要将Account声明为类而不是接口。