2

EF を介してテーブルを参照する LINQ クエリで where 句を動的に作成しようとしていますが、次のエラーが発生します。

'ClaimantLastName' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly. Near member access expression, line 6, column 2.

ここに私がしようとしているものがあります:

string whereClause = string.Format("ClaimantLastName = '{0}' and ClaimantSSN = '{1}'", lastName, ssn);

また、一重引用符なしで試してみましたが、役に立ちませんでした。

実際のクエリは次のとおりです。

return db.Claims.Where(whereClause).Select(
                    u => new AdvancedSearchResult
                    {
                        ClaimNumber = u.ClaimNumber,
.
.
.

私がやろうとしていることは可能ですか?それは本当に基本的なようです。どこが間違っていますか?

UPDATE : これが Claim エンティティです。

public static Claim CreateClaim(global::System.Int32 id, global::System.String claimantFirstName, global::System.String claimantLastName, global::System.String claimantSSN, global::System.DateTime dateOfInjury, global::System.String claimNumber, global::System.String claimantMiddleName, global::System.String claimantAddress1, global::System.String claimantAddress2, global::System.String claimantCity, global::System.String claimantState, global::System.String claimantZip, global::System.DateTime claimantDateOfBirth, global::System.String compensability, global::System.Boolean injuryType, global::System.String jurisdictionState, global::System.String status, global::System.String condition, global::System.String managingBranch, global::System.String bodyPart, global::System.String acceptedBodyPart, global::System.Boolean pGCase, global::System.String employersDefenseAttorney, global::System.String accidentDescription, global::System.String claimExaminerFirstName, global::System.String claimExaminerLastName, global::System.String claimExaminerEmail, global::System.String claimantAttorney, global::System.String workerId, global::System.String workerType)
{
    Claim claim = new Claim();
    claim.Id = id;
    claim.ClaimantFirstName = claimantFirstName;
    claim.ClaimantLastName = claimantLastName;
    claim.ClaimantSSN = claimantSSN;
    claim.DateOfInjury = dateOfInjury;
    claim.ClaimNumber = claimNumber;
    claim.ClaimantMiddleName = claimantMiddleName;
    claim.ClaimantAddress1 = claimantAddress1;
    claim.ClaimantAddress2 = claimantAddress2;
    claim.ClaimantCity = claimantCity;
    claim.ClaimantState = claimantState;
    claim.ClaimantZip = claimantZip;
    claim.ClaimantDateOfBirth = claimantDateOfBirth;
    claim.Compensability = compensability;
    claim.InjuryType = injuryType;
    claim.JurisdictionState = jurisdictionState;
    claim.Status = status;
    claim.Condition = condition;
    claim.ManagingBranch = managingBranch;
    claim.BodyPart = bodyPart;
    claim.AcceptedBodyPart = acceptedBodyPart;
    claim.PGCase = pGCase;
    claim.EmployersDefenseAttorney = employersDefenseAttorney;
    claim.AccidentDescription = accidentDescription;
    claim.ClaimExaminerFirstName = claimExaminerFirstName;
    claim.ClaimExaminerLastName = claimExaminerLastName;
    claim.ClaimExaminerEmail = claimExaminerEmail;
    claim.ClaimantAttorney = claimantAttorney;
    claim.WorkerId = workerId;
    claim.WorkerType = workerType;
    return claim;
}

更新: 試しに、Paul の提案したコードを追加しました。これは実際に機能します。

whereClause = string.Format("ClaimantLastName = \"{0}\" and ClaimantSSN = \"{1}\"", lastName, ssn);

                   List<URIntake.Claim> claims = new List<Claim>();
URIntake.Claim claim = new Claim();
claim.ClaimantFirstName = "Jay";
claim.ClaimantLastName = "Williams";
claim.ClaimantSSN = "654219870";
claim.ClaimantDateOfBirth = new DateTime(1993, 1, 2);
claims.Add(claim);

claim = new Claim();
claim.ClaimantFirstName = "Santa";
claim.ClaimantLastName = "Claus";
claim.ClaimantSSN = "012345678";
claim.ClaimantDateOfBirth = new DateTime(1893, 1, 2);
claims.Add(claim);

List<AdvancedSearchResult> selectedClaims = claims.AsQueryable().Where(whereClause).Select(
    u => new AdvancedSearchResult
    {
        ClaimNumber = u.ClaimNumber,
        DateOfBirth = u.ClaimantDateOfBirth,
        DateOfInjury = u.DateOfInjury,
        Denied = u.Compensability == "Denied"
    }).ToList();
4

5 に答える 5

8

System.Linq.Expressionsを使用した例を次に示します。ここでの例はクラスに固有のものClaimですが、このジェネリックのような関数を作成し、それらを使用してすべてのエンティティに対して動的に述語を構築できます。私は最近、すべてのクエリをハードコーディングすることなく、任意のエンティティ プロパティ (またはプロパティのグループ) 関数でエンティティの柔軟な検索をユーザーに提供するために使用しています。

public Expression<Func<Claim, Boolean>> GetClaimWherePredicate(String name, String ssn)
{
  //the 'IN' parameter for expression ie claim=> condition
  ParameterExpression pe = Expression.Parameter(typeof(Claim), "Claim");

  //Expression for accessing last name property
  Expression eLastName = Expression.Property(pe, "ClaimantLastName");

  //Expression for accessing ssn property
  Expression eSsn = Expression.Property(pe, "ClaimantSSN");

  //the name constant to match 
  Expression cName = Expression.Constant(name);

  //the ssn constant to match 
  Expression cSsn = Expression.Constant(ssn);

  //the first expression: ClaimantLastName = ?
  Expression e1 = Expression.Equal(eLastName, cName);

  //the second expression:  ClaimantSSN = ?
  Expression e2 = Expression.Equal(eSsn, cSsn);

  //combine them with and
  Expression combined = Expression.And(e1, e2);

  //create and return the predicate
  return Expression.Lambda<Func<Claim, Boolean>>(combined, new ParameterExpression[] { pe });
}
于 2013-02-15T22:42:43.923 に答える
6

私は個人的にPredicateBuilderを使用するのが本当に好きです。なぜなら、それはまだLINQのルックアンドフィールを持ち、マジックストリングではないからです。あらゆる種類の条件を設定してから、その述語に句を追加すると、すべてが適切にコンパイルされます。

http://www.albahari.com/nutshell/predicatebuilder.aspx

これが私自身のコードからの切り取ったサンプルです:

var predicate = PredicateBuilder.True<MarketingCabinetItem>();

//add vendor filter
if (vendorComboBox.SelectedValue != null && !String.IsNullOrEmpty(vendorComboBox.SelectedValue.ToString()))
{
    var vend = vendorComboBox.SelectedValue.ToString();
    predicate = predicate.And(m => m.Vendor == vend);
    vendPredicate.And(v => v.VendorName == vend);
}


//get all mkt item types in category
if (categoryComboBox.SelectedValue != null)
{
    var mktCatId = Guid.Parse(categoryComboBox.SelectedValue.ToString());
    predicate = predicate.And(p => p.CategoryCategoryId == mktCatId);
}

// get the marketing items using the inner and outer
var mktItems = (from mi in ctx.MarketingItem.AsExpandable()
                join mType in ctx.ItemType.AsExpandable() on mi.MarketingItemTypeId equals mType.Id
                join mktCat in ctx.Category.AsExpandable() on mType.MarketingItemCategoryId equals mktCat.Id
                join att in ctx.Attachment.AsExpandable() on mi.Id equals att.MarketingItemId
                join pri in ctx.Priority.AsExpandable() on mi.PriorityId equals pri.Id


                select new MarketingCabinetItem
                {
                   Id = mi.Id,
                   Title = mi.Title,
                   ItemTypeDescription = mType.Description,
                   PriorityLevel = pri.Level,
                   StartDate = mi.StartDate,
                   ExpirationDate = mi.ExpirationDate,
                   HasAttachments = att != null,
                   CategoryDescription = mktCat.Description
               }).Where(predicate).ToList();
于 2013-02-15T20:29:49.323 に答える
4

動的 linq を使用できる/使用する必要がある

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

db.Where("Something = @0 And SomethingElse = @1", "Blah", 42)

それがどのように処理されるかのようです(string.Formatの必要がないことに注意してください)

于 2013-02-15T19:07:15.840 に答える
1

簡単な方法は、LINQKITLINQExtensionを使用することです。

using (var context = new workEntities() )
{

    Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
    dictionary["Title"] = new List<string> {  
                    "Network Engineer", 
                    "Security Specialist", 
                    "=Web Developer"
                };
    dictionary["Salary"] = new List<string> { ">=2000" };
    dictionary["VacationHours"] = new List<string> { ">21" };
    dictionary["SickLeaveHours"] = new List<string> { "<5" };                
    dictionary["HireDate"] = new List<string> { 
                    ">=01/01/2000",
                    "28/02/2014" 
                };
    dictionary["ModifiedDate"] = new List<string> { DateTime.Now.ToString() };

    var data = context.Employee.CollectionToQuery(dictionary).ToList();
}
于 2014-03-02T21:37:51.420 に答える
1
    public class SearchField
    {
        public string Name { get; set; }
        public string @Value { get; set; }
        //public string Operator { get; set; }

        public SearchField(string Name, string @Value)
        {
            this.Name = Name;
            this.@Value = @Value;
            //Operator = "=";
        }
    }

    public class FilterLinq<T>
    {
        public static Expression<Func<T, Boolean>> GetWherePredicate(params SearchField[] SearchFieldList)
        {

            //the 'IN' parameter for expression ie T=> condition
            ParameterExpression pe = Expression.Parameter(typeof(T), typeof(T).Name);

            //combine them with and 1=1 Like no expression
            Expression combined = null;

            if (SearchFieldList != null)
            {
                foreach (var fieldItem in SearchFieldList)
                {
                    //Expression for accessing Fields name property
                    Expression columnNameProperty = Expression.Property(pe, fieldItem.Name);


                    //the name constant to match 
                    Expression columnValue = Expression.Constant(fieldItem.Value);

                    //the first expression: PatientantLastName = ?
                    Expression e1 = Expression.Equal(columnNameProperty, columnValue);

                    if (combined == null)
                    {
                        combined = e1;
                    }
                    else
                    {
                        combined = Expression.And(combined, e1);
                    }
                }
            }

            //create and return the predicate
            return Expression.Lambda<Func<T, Boolean>>(combined, new ParameterExpression[] { pe });
        }

    }

そして、あなたはそれをどのクラスでも呼び出すことができます

ClinicEntities x = new ClinicEntities();

  dataGridView1.DataSource = x.Patient
                          .Where(
FilterLinq<Patient>.GetWherePredicate(
new SearchField("PatientNameEnglish", "Mona Mohamed Ali"), 
new SearchField("PatientHusbandName", "Ahmed Sallam Kareem"))).ToList();

最後にbmusedに感謝

于 2013-05-20T09:17:26.320 に答える