我正在尝试在LINQ查询中动态构建一个where子句,该查询通过EF引用表,但是我收到以下错误:
'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,
.
.
.
我正在尝试做什么?这似乎很基本。我哪里错了?
更新:这是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;
}
更新:添加了保罗建议的代码作为试用版。这实际上有效。
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();
答案 0 :(得分:6)
以下是使用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 });
}
答案 1 :(得分:5)
我个人非常喜欢使用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();
答案 2 :(得分:4)
你可以/需要使用动态linq
db.Where("Something = @0 And SomethingElse = @1", "Blah", 42)
似乎是如何处理的(注意不需要string.Format)
答案 3 :(得分: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
答案 4 :(得分:0)
简单的方法是将LINQExtension与LINQKIT
一起使用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();
}