FindBy方法实体框架

时间:2013-02-14 12:01:01

标签: asp.net-mvc-3 entity-framework

我有帐户模型

 public class Account :IAggregateRoot
    { 
        public Account()
        {
        }
        public Account(Guid accountId)
        {
            Id = accountId;
        }

        public Guid Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
      }
}

存储库类

public class Repository<T> : IRepository<T> where T : class, IAggregateRoot
    {

        private readonly DbSet<T> _entitySet;

        public T FindBy(T entity)
        {
            return _entitySet.Find(entity);
        }
     }

现在当我想通过Id获取实体时,例如:

 public AccountViewModel GetAccountBy(Guid accountId)
        {
            var account = new Account(accountId);
            _unitOfWork.AccountRepository.FindBy(account);
            var accountView = account.ConvertToAccountView();
            return  accountView;
        }

我得到了错误

The specified parameter type is not valid. Only scalar types, such as System.Int32, System.Decimal, System.DateTime, and System.Guid, are supported.

我打电话给 GetAccountBy 的行为是这样的:

 public ActionResult Edit(Guid accountId)
        {
            var account = _accountService.GetAccountBy(accountId);
            return View(account);
        }

这有什么问题?非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用System.Int32和System.Guid调用DbSet.Find(params object [] keyValues)方法,如错误消息所示。 (以及System.Decimal,System.DateTime可能是复合键)

该方法不会在您的模型中查找Id或PK并自动使用它(当您通过Account时,该方法将不使用Account.Id) - 因为它使用“主键值”http://msdn.microsoft.com/en-us/library/gg696418(v=vs.103).aspx

考虑按FindBy Id method in EntityFramework

中的建议传递谓词

如果你的模型总是有类型指南的ID,那么也许你可以直接传递Id:

public T FindBy(T entity)
        {
            return _entitySet.Find(entity.Id);
        }

希望这有帮助。

答案 1 :(得分:1)

您未正确调用DBSet.Find()方法。

As the documentation states您需要传递

  

要查找的实体的主键值

如果您未传入实体的实例,则会传入标识实体的键值。从您的示例中,您不需要创建新的帐户实例:

var account = new Account(accountId);
_unitOfWork.AccountRepository.FindBy(account);

您只需将accountId传递给FindBy()

即可
_unitOfWork.AccountRepository.FindBy(accountId);

此处修改了您的代码:

public class Repository<T> : IRepository<T> where T : class, IAggregateRoot
{

    private readonly DbSet<T> _entitySet;

    public T FindBy(params Object[] keyValues)
    {
        return _entitySet.Find(keyValues)
    }
}

public AccountViewModel GetAccountBy(Guid accountId)
{
    _unitOfWork.AccountRepository.FindBy(accountId);
    var accountView = account.ConvertToAccountView();
    return  accountView;
}