使用 Nlinq 跨实体创建规范时遇到问题

发布于 2024-09-16 23:51:56 字数 2498 浏览 2 评论 0原文

我正在使用规范模式,并且有一个有效的实现(取自 WhoCanHelpMe Codeplex 项目),用于通过 NLinq、通用存储库和所有这些优点获取数据。

根方法是:

public IList<Case> GetCasesByUsername(string username)
{
    CaseByUserNameSpecification spc = new CaseByUserNameSpecification(username);
    return this.caseRepository.FindAll(spc).ToList();
}

FindAll() 方法执行以下操作:

public IQueryable<T> FindAll(ILinqSpecification<T, T> specification)
{
    return specification.SatisfyingElementsFrom(this.Session.Linq<T>());
}

并且 SatisfyingElementsFrom() 执行以下操作:

public virtual IQueryable<TResult> SatisfyingElementsFrom(IQueryable<T> candidates)
{
    if (this.MatchingCriteria != null)
    {
        return candidates.Where(this.MatchingCriteria).ToList().ConvertAll(this.ResultMap).AsQueryable();
    }

    return candidates.ToList().ConvertAll(this.ResultMap).AsQueryable();
}

因此,对于通过 Case 的 CaseNb 属性查询案例,它非常简单。像下面这样的规范适合我并获得我想要的案例。

public class CaseByCaseNbSpecification : QuerySpecification<User>
{
    private string caseNb;

    public CaseByCaseNbSpecification(string caseNb)
    {
        this.caseNb = caseNb;
    }

    public string UserName
    {
        get { return this.caseNb; }
    }

    public override Expression<Func<Case, bool>> MatchingCriteria
    {
        get { return u => u.CaseNb.Equals(this.caseNb, StringComparison.CurrentCultureIgnoreCase); }
    }

}

但是,我不知道在跨越多个实体时如何做到这一点。我想要的是一个规范,允许我按用户名获取案例。基本上,在数据库中,有三个表,这些表已被带入实体中。这是实体:

这是 Case 类:

public class Case : Entity
{
    private ICollection<CaseUser> caseUsers = new HashSet<CaseUser>();

    public virtual Patient Patient { get; set; }
    public virtual string CaseNb { get; set; }
    ...
    public virtual IEnumerable<CaseUser> CaseUsers { get { return caseUsers; } }
}

这是 CaseUser:

public class CaseUser : Entity
{
    public virtual Case Case { get; set; }
    public virtual User User { get; set; }
    ...
}

并且,User:

public class User : Entity
{
    private ICollection<CaseUser> caseUsers = new HashSet<CaseUser>();

    public virtual Account Account { get; set; }
    public virtual string UserName { get; set; }
    ...
    public virtual IEnumerable<CaseUser> CaseUsers { get { return caseUsers; } }
}

我将如何编写表达式来获取关联表中的数据?

I am using the Specification pattern, and have a working implementation (taken from the WhoCanHelpMe Codeplex project) for getting data via NLinq, generic repositories and all that goodness.

The root method is:

public IList<Case> GetCasesByUsername(string username)
{
    CaseByUserNameSpecification spc = new CaseByUserNameSpecification(username);
    return this.caseRepository.FindAll(spc).ToList();
}

The FindAll() method does the following:

public IQueryable<T> FindAll(ILinqSpecification<T, T> specification)
{
    return specification.SatisfyingElementsFrom(this.Session.Linq<T>());
}

And, SatisfyingElementsFrom() does this:

public virtual IQueryable<TResult> SatisfyingElementsFrom(IQueryable<T> candidates)
{
    if (this.MatchingCriteria != null)
    {
        return candidates.Where(this.MatchingCriteria).ToList().ConvertAll(this.ResultMap).AsQueryable();
    }

    return candidates.ToList().ConvertAll(this.ResultMap).AsQueryable();
}

So, for querying cases by CaseNb property of a Case, it's pretty straight-forward. A Specification like the one below works for me and gets the cases I'd want.

public class CaseByCaseNbSpecification : QuerySpecification<User>
{
    private string caseNb;

    public CaseByCaseNbSpecification(string caseNb)
    {
        this.caseNb = caseNb;
    }

    public string UserName
    {
        get { return this.caseNb; }
    }

    public override Expression<Func<Case, bool>> MatchingCriteria
    {
        get { return u => u.CaseNb.Equals(this.caseNb, StringComparison.CurrentCultureIgnoreCase); }
    }

}

However, I am at a loss to understand how to do this when crossing multiple entities. What I'd like to have is a Specification that allows me to get Cases by UserName. Basically, in the database, there are three tables and these have been carried into entities. Here's are entities:

Here's the Case class:

public class Case : Entity
{
    private ICollection<CaseUser> caseUsers = new HashSet<CaseUser>();

    public virtual Patient Patient { get; set; }
    public virtual string CaseNb { get; set; }
    ...
    public virtual IEnumerable<CaseUser> CaseUsers { get { return caseUsers; } }
}

Here's the CaseUser:

public class CaseUser : Entity
{
    public virtual Case Case { get; set; }
    public virtual User User { get; set; }
    ...
}

And, User:

public class User : Entity
{
    private ICollection<CaseUser> caseUsers = new HashSet<CaseUser>();

    public virtual Account Account { get; set; }
    public virtual string UserName { get; set; }
    ...
    public virtual IEnumerable<CaseUser> CaseUsers { get { return caseUsers; } }
}

How would I write the Expression to get the data across the association table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长途伴 2024-09-23 23:51:56

我相信您的规范实现应该如下所示:

public class CaseByUsernameSpecification : QuerySpecification<Case> 
{ 
    private string userName; 

    public CaseByUsernameSpecification(string userName) 
    { 
        this.userName = userName; 
    } 

    public string UserName 
    { 
        get { return this.userName; } 
    } 

   public override Expression<Func<Case, bool>> MatchingCriteria 
    { 
        get { return c => c.CaseUsers.Any(cu => cu.User.Username == this.userName); } 
    } 

}

I believe your specification implementation should look something like this:

public class CaseByUsernameSpecification : QuerySpecification<Case> 
{ 
    private string userName; 

    public CaseByUsernameSpecification(string userName) 
    { 
        this.userName = userName; 
    } 

    public string UserName 
    { 
        get { return this.userName; } 
    } 

   public override Expression<Func<Case, bool>> MatchingCriteria 
    { 
        get { return c => c.CaseUsers.Any(cu => cu.User.Username == this.userName); } 
    } 

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文