在LINQ to EF查询中生成动态where子句

kmynzznz  于 2022-12-25  发布在  其他
关注(0)|答案(5)|浏览(135)

我试图在一个通过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:这是索赔实体。

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

vwhgwdsa1#

这里是一个使用System.Linq.Expressions的例子。虽然这里的例子是特定于你的Claim类的,但是你可以使这样的函数通用,然后使用它们为你的所有实体动态地构建 predicate 。我最近一直在使用为用户提供一个灵活的搜索实体的任何实体属性(或属性组)函数,而不必硬编码所有的查询。

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

umuewwlo2#

我个人真的很喜欢使用PredicateBuilder,因为它仍然有LINQ的外观和感觉,而不是一些神奇的字符串。你可以有各种各样的条件,然后添加子句到 predicate ,它会为你编译得很好,很干净。
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();
llmtgqce

llmtgqce3#

您可以/需要使用动态链接
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
第一个月
看起来是如何处理的(注意不需要string.Format)

ahy6op9u

ahy6op9u4#

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**

qlvxas9a

qlvxas9a5#

最简单方法是将LINQExtensionLINQKIT一起使用

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

相关问题