0

フィルタリングしているフィールドがリターンセットの一部ではないlinqクエリに動的where句を追加するにはどうすればよいのでしょうか。

クエリ:

(from p in db.Person
join c in db.Client on p.PersonId equals c.PersonId into c_join
from c in c_join.DefaultIfEmpty()
join pt in db.PersonType on p.PersonTypeId equals pt.PersonTypeId into pt_join
from pt in pt_join.DefaultIfEmpty()
join pl in db.Plan on c.ClientId equals pl.ClientId into pl_join
from pl in pl_join.DefaultIfEmpty()
join plt in db.PlanType on pl.PlanTypeId equals plt.PlanTypeId into plt_join
from plt in plt_join.DefaultIfEmpty()
orderby pt.PersonTypeDescription ascending , p.LastName ascending
select new ExtendedPersonSearch
{
PersonId = p.PersonId,
FirstName = p.FirstName,
LastName = p.LastName,
MiddleName = p.MiddleName,
Aka = p.Aka,
Sin = p.Sin,
PersonTypeId = pt.PersonTypeId,
PersonTypeDescription = pt.PersonTypeDescription,
ClientId = (Int32?) c.ClientId
}).Distinct();

関連クラス:

 public class ExtendedPersonSearch
    {
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string MiddleName { get; set; }
        public string Aka { get; set; }
        public string Sin { get; set; }
        public int PersonTypeId { get; set; }
        public string PersonTypeDescription { get; set; }
        public int? AddressId { get; set; }
        public string Street1 { get; set; }
        public int? ClientId { get; set; }

しかし、ExtendedPersonSearchクラスの一部ではないpl.PlanIdでフィルターを実行したいと思います。

これらの他のタイプの動的where句は、リターンセット内のアイテムに対して機能します。

 if (fd.Contains("txtSearchFirstName"))
                {
                    var searchFirstName = form[fd];
                    ViewData["searchFirstName"] = searchFirstName;

                    if (searchFirstName != "")
                        qryAllPerson = qryAllPerson.Where(sp => sp.FirstName.Contains(searchFirstName));

                }

このクエリを取得するためにユーザーがプランIDを入力したかどうかに基づいて、クエリを再度書き込むことはできません。

qryAllPerson = (from p in db.Person
join c in db.Client on p.PersonId equals c.PersonId into c_join
from c in c_join.DefaultIfEmpty()
join pt in db.PersonType on p.PersonTypeId equals pt.PersonTypeId into pt_join
from pt in pt_join.DefaultIfEmpty()
join pl in db.Plan on c.ClientId equals pl.ClientId into pl_join
from pl in pl_join.DefaultIfEmpty()
join plt in db.PlanType on pl.PlanTypeId equals plt.PlanTypeId into plt_join
from plt in plt_join.DefaultIfEmpty()
orderby pt.PersonTypeDescription ascending, p.LastName ascending
where pl.PlanId == searchPlanId
select new ExtendedPersonSearch
{
PersonId = p.PersonId,
FirstName = p.FirstName,
LastName = p.LastName,
MiddleName = p.MiddleName,
Aka = p.Aka,
Sin = p.Sin,
PersonTypeId = pt.PersonTypeId,
PersonTypeDescription = pt.PersonTypeDescription,
ClientId = (Int32?)c.ClientId
}).Distinct();

クエリ全体を再度入力する代わりに、PlanIdのwhere句を追加する方法はありますか?

4

1 に答える 1

1

他の動的検索は、拡張検索クラスのプロパティであるため、機能します。

クエリを実行すると、列挙可能なExtendedPersonSearchオブジェクトが返されます。これを取り戻すと、そのオブジェクトに存在するプロパティでのみフィルタリングできます。

実生活と同じように、ペットが持っているCPUコアの数でペットをフィルタリングすることはできませんでした(単に意味がありません)。

単一のクエリが必要な場合は、行を変更できます

where pl.PlanId == searchPlanId

することが

where (searchPlanId == null || pl.PlanId == searchPlanId)

そうすれば、検索プランが入力されていない場合、条件の最初の部分がヒットし、短絡してすべてのレコードが返されます。検索プランIDが入力された場合、最初の句はfalseであるため、C#は2番目の句に移動し、pl.PlanIdが入力されたsearchPlanIdと等しいことを確認します。

または、PlanIdをExtendedPersonSearchオブジェクトに追加し、データソースから取得した後にフィルタリングすることもできます。ただし、プランIDと一致しない結果を除外すると、大量のデータをプルバックしてほとんどのデータを破棄するため、これはおそらく最善のアイデアではありません。

于 2013-03-26T21:41:20.077 に答える