I am creating a simple WebApi for Recipes. A recipe contains both ingredients and instructions. I think I got most of the WebApi down, except for the Update() part.
I am not quite sure if I am doing it the right way. My code looks very long and complicated.
Is there an easier way to update parent and all children?
public async Task<IActionResult> Update(int id, [FromBody] RecipeViewModel recipeViewModel)
{
var recipeToUpdate = _unitOfWork.RecipeRepository.Get(filter: r => r.RecipeId == id,
includeProperties: "Ingredients,Instructions").FirstOrDefault();
recipeToUpdate.Name = recipeViewModel.Name;
recipeToUpdate.Description = recipeViewModel.Description;
recipeToUpdate.Image = recipeViewModel.Image;
foreach (var oldIngredient in recipeToUpdate.Ingredients)
{
var newIngredient = recipeViewModel.Ingredients.Where(ingredient => ingredient.IngredientId == oldIngredient.IngredientId).FirstOrDefault();
if (newIngredient == null)
{
recipeToUpdate.Ingredients.Remove(oldIngredient);
_unitOfWork.IngredientRepository.Delete(oldIngredient);
}
else
{
oldIngredient.Value = newIngredient.Value;
oldIngredient.Name = newIngredient.Name;
oldIngredient.Position = newIngredient.Position;
oldIngredient.Unit = newIngredient.Unit;
_unitOfWork.IngredientRepository.Update(newIngredient);
}
}
foreach (var newIngredient in recipeViewModel.Ingredients)
{
var oldIngredient = recipeToUpdate.Ingredients.Where(ingredient => ingredient.IngredientId == newIngredient.IngredientId).FirstOrDefault();
if (oldIngredient == null)
{
recipeToUpdate.Ingredients.Add(newIngredient);
_unitOfWork.IngredientRepository.Insert(newIngredient);
}
else
{
oldIngredient.Value = newIngredient.Value;
oldIngredient.Name = newIngredient.Name;
oldIngredient.Position = newIngredient.Position;
oldIngredient.Unit = newIngredient.Unit;
_unitOfWork.IngredientRepository.Update(oldIngredient);
}
}
foreach (var oldInstruction in recipeToUpdate.Instructions)
{
var newInstruction = recipeViewModel.Instructions.Where(instruction => instruction.InstructionId == oldInstruction.InstructionId).FirstOrDefault();
if (newInstruction == null)
{
recipeToUpdate.Instructions.Remove(oldInstruction);
_unitOfWork.InstructionRepository.Delete(oldInstruction);
}
else
{
oldInstruction.Position = newInstruction.Position;
oldInstruction.Description = newInstruction.Description;
_unitOfWork.InstructionRepository.Update(oldInstruction);
}
}
foreach (var newInstruction in recipeViewModel.Instructions)
{
var oldInstruction = recipeToUpdate.Instructions.Where(instruction => instruction.InstructionId == newInstruction.InstructionId).FirstOrDefault();
if (oldInstruction == null)
{
recipeToUpdate.Instructions.Add(newInstruction);
_unitOfWork.InstructionRepository.Insert(newInstruction);
}
else
{
oldInstruction.Position = newInstruction.Position;
oldInstruction.Description = newInstruction.Description;
_unitOfWork.InstructionRepository.Update(oldInstruction);
}
}
_unitOfWork.RecipeRepository.Update(recipeToUpdate);
await _unitOfWork.Save()
}
And these are my models and my view model:
public class Recipe
{
public int RecipeId { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")]
public DateTime? CreationDate { get; set; }
[JsonIgnore]
public virtual IdentityUser? Creator { get; set; }
[Required(ErrorMessage = "A recipe must have a name"), MaxLength(254)]
public string? Name { get; set; }
[Required(ErrorMessage = "A recipe must have a description"), MaxLength(254)]
public string? Description { get; set; }
public virtual ICollection<Ingredient>? Ingredients { get; set; }
public virtual ICollection<Instruction>? Instructions { get; set; }
public string? Image { get; set; }
}
public class Ingredient
{
public int IngredientId { get; set; }
public int Position { get; set; }
[Required(ErrorMessage = "An ingredient must have a value")]
public Decimal? Value { get; set; }
[Required(ErrorMessage = "An ingredient must have a unit")]
public string? Unit { get; set; }
[Required(ErrorMessage = "An ingredient must have a name")]
public string? Name { get; set; }
}
public class Instruction
{
public int InstructionId { get; set; }
public int Position { get; set; }
[Required(ErrorMessage = "An instruction cannot be empty")]
public string? Description { get; set; }
}
public class RecipeViewModel
{
[Required(ErrorMessage = "A recipe must have a name"), MaxLength(254)]
public string? Name { get; set; }
[Required(ErrorMessage = "A recipe must have a description"), MaxLength(254)]
public string? Description { get; set; }
public ICollection<Ingredient>? Ingredients { get; set; }
public ICollection<Instruction>? Instructions { get; set; }
public string? Image { get; set; }
}
Appreciate any help, thanks.
Related
I am new to .NetCore and Blazor. I am trying to do a POST of an new Anime, but I am allways getteing the error "The Genre field is required." I have added the genreId to the JSON Object but still the same error -> Screenshot of the error
It's one to many relation, where one animal can have only one genre but one genre can have many enemies.
I don't know if it's useful but here are screenshots of my two tables in the DB -> Anime table and the Genre tab
Here are my to Models:
Anime model
public class Anime
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string CoverImage { get; set; } = string.Empty;
public string Author { get; set; } = string.Empty;
public Genre Genre { get; set; }
public string Studio { get; set; } = string.Empty;
public DateTime? ReleaseDate { get; set; }
public DateTime? EndDate { get; set; }
}
Genre model
public class Genre
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[JsonIgnore]
public List<Anime> Animes { get; set; }
}
AnimeService where I am adding the new anime to the DB
public async Task<ServiceResponse<List<Anime>>> AddAnime(Anime NewAnime)
{
ServiceResponse<List<Anime>> serviceResponse = new ServiceResponse<List<Anime>>();
_dataContext.Animes.Add(NewAnime);
await _dataContext.SaveChangesAsync();
var animes = await _dataContext.Animes
.Include(a => a.Genre)
.ToListAsync();
if (animes == null)
{
serviceResponse.Success = false;
serviceResponse.Message = "Animes could be found!";
}
serviceResponse.Data = animes;
return serviceResponse;
}
AnimeController
[HttpPost]
[Route("AddAnime")]
public async Task<ActionResult<ServiceResponse<List<Anime>>>> AddAnime(Anime NewAnime)
{
return Ok(await _animeService.AddAnime(NewAnime));
}
As we discussed on Discord:
You're using .NET 6 with nullables enabled.
As an Anime can exist before it has Genre assigned I would configure the tables like this:
public class Anime
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string CoverImage { get; set; } = string.Empty;
public string Author { get; set; } = string.Empty;
public int? GenreId { get; set; }
[ForeignKey(nameof(GenreId))]
public Genre? Genre { get; set; }
public string Studio { get; set; } = string.Empty;
public DateTime? ReleaseDate { get; set; }
public DateTime? EndDate { get; set; }
}
public class Genre
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
[JsonIgnore]
[InverseProperty(nameof(Anime.Genre))]
public List<Anime> Animes { get; set; }
}
It seems that your Anime instance don't habe a Genre object but it is requiered in your db context
You have to add navigation property GenreId as nullable if you think that Genre is optional
public class Anime
{
public int Id { get; set; }
... another properties
public int? GenreId { get; set; }
public virtual Genre Genre { get; set; }
}
after this you will have to make a new database migration
I really thought I understood what I was doing, but here goes. I decided I need more properties in my View so I created a ViewModel called ViewDataset and replaced the original Dataset model in the View. On my HttpGet TestDataset the View Model is populated correctly with data from the Viewmodel:
My original dataset that was working is below:
public class Dataset
{
public int Dataset_ID { get; set; }
public int Category_ID { get; set; }
public string Provider { get; set; }
public string Name { get; set; }
public string Institution { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public bool Domestic { get; set; }
public bool International { get; set; }
public bool Includes_PHI { get; set; }
public bool PHI_Limited { get; set; }
public bool Includes_PIL { get; set; }
public bool PIL_Limited { get; set; }
public bool Citation_Requirements { get; set; }
public string Citation_Comments { get; set; }
public Nullable<System.DateTime> Availability_Beg_DT { get; set; }
public Nullable<System.DateTime> Availability_End_DT { get; set; }
public bool Subscription_Renewal { get; set; }
public Nullable<System.DateTime> Subscription_Renewal_DT { get; set; }
public bool Retention_Expiry { get; set; }
public Nullable<System.DateTime> Retention_Expiry_DT { get; set; }
public bool Data_Destruction { get; set; }
public Nullable<System.DateTime> Data_Destruction_DT { get; set; }
public string Data_Destruction_Instructions { get; set; }
public Nullable<int> Contract_ID { get; set; }
public bool Draft_Status { get; set; }
public bool Admin_Only { get; set; }
public string Dataset_Alias { get; set; }
public bool Loc_Amazon { get; set; }
public bool Loc_IT_Research { get; set; }
public bool Loc_Research_Proj { get; set; }
public bool Loc_Secure_Data { get; set; }
public bool Loc_Mercury { get; set; }
public bool Loc_Research_CC { get; set; }
public bool Loc_Research_VM { get; set; }
public bool Loc_External { get; set; }
public bool Access_Url { get; set; }
public bool Access_Download_App { get; set; }
public bool Access_Lab_Terminal { get; set; }
public bool Access_Email_Req { get; set; }
public bool Access_File_Download { get; set; }
public bool Access_Other { get; set; }
public string Location_Notes { get; set; }
public string Access_Notes { get; set; }
public Nullable<System.DateTime> Date_Added { get; set; }
public Nullable<System.DateTime> Date_Modified { get; set; }
public string Added_By_User { get; set; }
public string Updated_By_User { get; set; }
public bool External_Collaborators
{
get; set;
}
}
Here is my new ViewDataset (viewmodel)
public class ViewDataset
{
public Dataset dataset;
public List<SelectListItem> categories_list;
}
Here is my is a sample of my view ... couple of lines, but the view is populated correctly with data from the ViewDataset model
#model ResearchDataInventoryWeb.Models.ViewDataset
<td>
#Html.TextBoxFor(model => model.dataset.Institution, new { placeholder = "<Institution>", #class = "input-box" })
</td>
<td>
#Html.TextBoxFor(model => model.dataset.Name, new { placeholder = "<Dataset Name>", #class = "input-box" })
</td>
#Html.CheckBoxFor(model => model.dataset.Domestic) <span class="display-checkbox">Domestic</span>
#Html.CheckBoxFor(model => model.dataset.International) <span class="display-checkbox">International</span>
#Html.CheckBoxFor(model => model.dataset.Includes_PHI) <span class="display-checkbox">Includes PHI </span>
#Html.CheckBoxFor(model => model.dataset.Includes_PIL) <span class="display-checkbox">Includes PII </span><br />
#Html.CheckBoxFor(model => model.dataset.External_Collaborators) <span class="display-checkbox">External Collaborators Allowed (Sharable)</span>
#Html.CheckBoxFor(model => model.dataset.Citation_Requirements) <span class="display-checkbox">Citation Requirements</span>
<input type="submit" value="TestPost" />
Here is my HttpPost TestDataset : The model Viewdataset (dataset, categories_list) properties that I am passing back from the view are NULL, am I missing something?
[HttpPost]
public ActionResult TestDataset(ViewDataset viewdataset)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:4251/");
//HTTP POST
viewdataset.dataset.Category_ID = 2;
viewdataset.dataset.Dataset_ID = 1;
viewdataset.dataset.Location = "Fingers Crossed";
viewdataset.dataset.Institution = "Not Null";
var dataset = viewdataset.dataset;
// var postTask = client.PostAsJsonAsync<Dataset>("api/datasets/1", dataset);
var postTask = client.PostAsJsonAsync("api/datasets/1", dataset);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
}
ModelState.AddModelError(string.Empty, "Server Error. Please contact administrator.");
return View(viewdataset);
}
Here if my HttpGet TestDataset in case you need to see it
public async Task<ActionResult> TestDataset()
{
//Hosted web API REST Service base url
string Baseurl = "http://localhost:4251/";
List<Dataset> dataset = new List<Dataset>();
List<Category> categories = new List<Category>();
var parm = "1";
var returned = new Dataset();
var ViewDataset = new ViewDataset();
using (var client = new HttpClient())
{
//Passing service base url
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Sending request to find web api REST service resource GetAllEmployees using HttpClient
HttpResponseMessage Res = await client.GetAsync("api/Datasets/" + parm);
HttpResponseMessage Res2 = await client.GetAsync("api/Categories");
//Checking the response is successful or not which is sent using HttpClient
if (Res.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
var EmpResponse = Res.Content.ReadAsStringAsync().Result;
//Deserializing the response recieved from web api and storing into the Employee list
returned = JsonConvert.DeserializeObject<Dataset>(EmpResponse);
}
if (Res2.IsSuccessStatusCode)
{
//Storing the response details recieved from web api
var CatResp = Res2.Content.ReadAsStringAsync().Result;
//Deserializing the response recieved from web api and storing into the Employee list
categories = JsonConvert.DeserializeObject<List<Category>>(CatResp);
}
// Create the Categories Select List
var categoryList = new List<SelectListItem>();
foreach (Category c in categories)
{
categoryList.Add(new SelectListItem
{
Value = c.Category_ID.ToString(),
Text = c.Description,
Selected = (c.Category_ID == returned.Category_ID ? true : false)
});
}
ViewDataset.dataset = returned;
ViewDataset.categories_list = categoryList;
//returned.External_Collaborators = returned.External_Collaborators == null || false ? false : true;
//returning the employee list to view
return View(ViewDataset);
}
}
Try to change
public class ViewDataset
{
public Dataset dataset;
public List<SelectListItem> categories_list;
}
to
public class ViewDataset
{
public Dataset dataset { get; set; }
public List<SelectListItem> categories_list { get; set; }
}
Hello I have problem in one query. Why it's always return no value.
public List<UserDetail> userSearchModel(UserSearchModel searchModel)
{
string userid = User.Identity.GetUserId();
var user = _dbContext.UserDetails.Where(x => x.Id == userid);
var result = _dbContext.UserDetails.Except(user).ToList().AsQueryable();
if (searchModel != null)
{
if (searchModel.LanguageId.Count() != 0)
{
List<UserDetailLanguage> usrDetails = new List<UserDetailLanguage>();
foreach (var item in searchModel.LanguageId)
{
var details = _dbContext.UserDetailLanguages.Where(x => x.LanguageId == item).ToList();
foreach (var item2 in details)
{
usrDetails.Add(item2);
}
}
result = result.Where(x => x.UserDetailLanguages == usrDetails);
}
}
return result.ToList();
}
I want to get results which are the same in usrDetails list and in result.UserDetailLanguages.
In result.UserDetailLanguages I have record equals to record in usrDetails but this not want retrieve.
Here is my model:
public class UserDetail
{
public UserDetail()
{
this.UserDetailLanguages = new HashSet<UserDetailLanguage>();
}
[Key, ForeignKey("User")]
public string Id { get; set; }
public DateTime Birthday { get; set; }
public string Sex { get; set; }
public string Country { get; set; }
public string About { get; set; }
[NotMapped]
public int Age { get { return DateTime.Now.Year - Birthday.Year; } }
public virtual ApplicationUser User { get; set; }
public virtual ICollection<UserDetailLanguage> UserDetailLanguages { get; set; }
}
public class UserDetailLanguage
{
public Int32 Id { get; set; }
public virtual UserDetail UserDetail { get; set; }
public string UserDetailId { get; set; }
public virtual Language Language { get; set; }
public Int32 LanguageId { get; set; }
public Boolean IsKnown { get; set; }
public static implicit operator List<object>(UserDetailLanguage v)
{
throw new NotImplementedException();
}
}
public class Language
{
public Language()
{
this.UserDetailLanguages = new HashSet<UserDetailLanguage>();
}
public int Id { get; set; }
public string Value { get; set; }
public string Name { get; set; }
public virtual ICollection<UserDetailLanguage> UserDetailLanguages { get; set; }
}
What I'm doing wrong?
If you want to see if your value is in a list you use the Contains function of the list -- like this:
result = result.Where(x => usrDetails.Contains(x.UserDetailLanguage));
If you want to see if there are any items in both lists you can use intersection like this:
result = result.Where(x => usrDetails.Intersect(x.UserDetailLanguage).Count() > 0);
Looks like you are checking equality between lists in following code
result = result.Where(x => x.UserDetailLanguages == usrDetails);
This might not work, to check equality for lists you can use something like
Enumerable.SequenceEqual(FirstList.OrderBy(fList => fList),
SecondList.OrderBy(sList => sList))
I have this controller to update information in database:
public ActionResult EditOwner(Owner owner, int? [] selectedNewCars)
{
var newOwner = new Owner();
newOwner.Name = owner.Name;
newOwner.Surname = owner.Surname;
newOwner.Birthday = owner.Birthday;
newOwner.ExperienceInYears = owner.ExperienceInYears;
newOwner.OwnerId = owner.OwnerId;
newOwner.Cars.Clear();
if (selectedNewCars != null)
{
foreach (int carId in selectedNewCars)
{
var car = db.GetCar(carId);
newOwner.Cars.Add(car);
}
}
db.UpdateOwner(newOwner);
return RedirectToAction("OwnersInfo");
}
and this to update entry from repository class:
public void UpdateOwner(Owner item)
{
db.Entry(item).State = EntityState.Modified;
Save();
}
Get car by id:
public Car GetCar(int id)
{
return db.Cars.Include(p => p.Owners).FirstOrDefault(x => x.CarId == id);
}
Car model:
public class Car
{
[HiddenInput(DisplayValue = false)]
public int CarId { get; set; }
[Required]
[Display(Name = "Car model")]
public string Model { get; set; }
[Required]
[Display(Name = "Car mk.")]
public string Mk { get; set; }
[Required]
[Display(Name = "Car price")]
[DataType(DataType.Currency)]
public double Price { get; set; }
[Required]
[Display(Name = "Release Date")]
public int ReleaseDate { get; set; }
[Required]
[Display(Name = "Car type")]
public CarType Type { get; set; }
[HiddenInput(DisplayValue = false)]
public List<Owner> Owners { get; }
public Car()
{
Owners = new List<Owner>();
}
}
Owner model:
public class Owner
{
[HiddenInput(DisplayValue = false)]
public int OwnerId { get; set; }
[Required]
[Display(Name = "Client name")]
public string Name { get; set; }
[Required]
[Display(Name = "Client surname")]
public string Surname { get; set; }
[Required]
[Display(Name = "Client birthday")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime Birthday { get; set; }
[Required]
[Display(Name = "Client experience(in years)")]
public int? ExperienceInYears { get; set; }
[Display(Name = "Select car")]
public List<Car> Cars { get; set; }
public Owner()
{
Cars = new List<Car>();
}
}
My problem is this exception of EF:
enter image description here
Can anyone help? I have spent several days trying to resolve it and nothing..
i found a problem. "owner" object must be recived from database, then modified, like this:
public ActionResult EditOwner(Owner owner, int? [] selectedNewCars)
{
var newOwner = db.GetOwner(owner.OwnerId);
newOwner.Name = owner.Name;
newOwner.Surname = owner.Surname;
newOwner.Birthday = owner.Birthday;
newOwner.ExperienceInYears = owner.ExperienceInYears;
newOwner.OwnerId = owner.OwnerId;
newOwner.Cars.Clear();
if (selectedNewCars != null)
{
foreach (int carId in selectedNewCars)
{
var car = db.GetCar(carId);
newOwner.Cars.Add(car);
}
}
db.UpdateOwner(newOwner);
return RedirectToAction("OwnersInfo");
}
This question builds on the following question (s)
Indexing : How do I construct my RavenDb static indexes for this document, given these requirements?
Simple Where clause with paging : How to construct a proper WHERE clause with RavenDb
The essence of the question is how do I dynamically add or remove fields to participate in a where clause?
Document:
[Serializable]
public class Product
{
public string AveWeight { get; set; }
public string BrandName { get; set; }
public string CasePack { get; set; }
public string Catalog { get; set; }
public decimal CatalogId { get; set; }
public decimal CategoryId { get; set; }
public string Info { get; set; }
public bool IsOfflineSupplierItem { get; set; }
public bool IsRebateItem { get; set; }
public bool IsSpecialOrderItem { get; set; }
public bool IsSpecialPriceItem { get; set; }
public bool IsTieredPricingItem { get; set; }
public string ItemNum { get; set; }
public string ManufactureName { get; set; }
public string ManufactureNum { get; set; }
public decimal OffineSupplierId { get; set; }
public string PackageRemarks { get; set; }
public decimal Price { get; set; }
public decimal PriceGroupId { get; set; }
public decimal ProductId { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public string SupplierName { get; set; }
public string UOM { get; set; }
public string Upc { get; set; }
public string Url { get; set; }
}
Index:
if (store.DatabaseCommands.GetIndex("Products_Index") == null)
{
store.DatabaseCommands.PutIndex("Products_Index", new IndexDefinitionBuilder<Product>
{
Map = products => from p in products
select new { p.CatalogId,
p.HasPicture,
p.INFO2,
p.IsOfflineSupplierItem,
p.IsRebateItem,
p.IsSpecialOrderItem,
p.IsSpecialPriceItem,
p.IsTieredPricingItem,
p.Price },
Indexes =
{
{ x => x.INFO2, FieldIndexing.Analyzed },
{ x => x.CatalogId, FieldIndexing.Default},
{ x => x.HasPicture, FieldIndexing.Default},
{ x => x.IsOfflineSupplierItem, FieldIndexing.Default},
{ x => x.IsRebateItem, FieldIndexing.Default},
{ x => x.IsSpecialOrderItem, FieldIndexing.Default},
{ x => x.IsSpecialPriceItem, FieldIndexing.Default},
{ x => x.IsTieredPricingItem, FieldIndexing.Default},
{ x => x.Price, FieldIndexing.Default}
}
});
}
Naive Where clause
string t1 = "foo";
bool t2 = true;
decimal t3 = 100m;
products = DocumentSession.Query<Product>()
.Statistics(out stats)
.Where(p => p.INFO2.StartsWith(t1) && p.IsRebateItem == t2 && p.CatalogId = t3)
.OrderByField(columnToSortBy, columnToSortByAsc)
.Skip(pageIndex * pageSize)
.Take(pageSize)
.ToList()
;
First Pass at Advanced Query
var products = s.Advanced.LuceneQuery<Product>("Products")
.WhereEquals("Catalog", "National Catalog")
.ToList()
;
which throws an exception
A first chance exception of type 'Lucene.Net.QueryParsers.QueryParser.LookaheadSuccess' occurred in Lucene.Net.dll
A first chance exception of type 'System.IO.IOException' occurred in Lucene.Net.dll
Second pass (works)
result = s.Advanced.LuceneQuery<Product>("Products_Index")
.Where("CatalogId:(736275001) AND HasPicture:(true) AND IsOfflineSupplierItem:(false)")
.ToArray();
Third Pass (and fastest yet)
result = s.Advanced.LuceneQuery<Product>("Products/Index")
.Statistics(out stats)
.WhereStartsWith("INFO2", "ink")
.AndAlso()
.WhereStartsWith("INFO2", "pen")
.AndAlso()
.WhereEquals("CatalogId", 736275001)
.AndAlso()
.WhereEquals("HasPicture", true)
.AndAlso()
.WhereEquals("IsOfflineSupplierItem", false)
.AndAlso()
.WhereEquals("IsRebateItem", false)
.AndAlso()
.WhereEquals("IsSpecialOrderItem", false)
.AndAlso()
.WhereEquals("IsSpecialPriceItem", false)
.ToArray()
;
If you want to do this dynamically, you can use the DocumentSession.Advanced.LuceneQuery, which allows you to pass strings as the property names for the index.
That way, you don't have to deal with the strongly typed issues.