How to avoid null values in LINQ command? - c#

I am trying to search the object from its list using entity framework.
I have following structure of the object
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public double Size { get; set; }
}
and I create the list of the product
private List<Product> AddProducts()
{
List<Product> ProductList = new List<Product>();
oProduct Product = new Product();
oProduct.Id = 1;
oInventory.ProductName = "Product1";
oProduct.Size = 25;
ProductList.Add(oProduct);
oProduct Product = new Product();
oProduct.Id = 2;
oInventory.ProductName = "Product2";
oProduct.Size = 25;
ProductList.Add(oProduct);
return ProductList;
}
Now, I am trying to search the object form the above list form ProductName parameter.
I have used below code.
public ActionResult Index(string productname = "", string size = "")
{
var oProdList = from ProdList in AddProducts() select oProdList;
oProdList = oProdList.Where(oProd => oProd.ProductName.ToUpper().Contains(ProductName.ToUpper().Trim())|| oProd.Size.ToString().ToUpper().Contains(size.ToUpper().Trim()));
ViewBag.ProductList = oProdList;
return View();
}
Now Please check picture below, I have list of products and I am trying to find the Product1 by typing it in text box and I keep the size textbox blank.
now when I click on submit , I pass these two varibles for searching in Index method (above one) but the LINQ command returns the both records, Product1 and Product 2
but it should return only one record
How to deal with this ?

This worked for me and is how a search algorithm should work. You want to && the parameters if they are both provided but || them if one of the arguments is missing.
Also its good to note that an input of "2" will match "25" for the size because we are preforming a Contains. If you want it only to match when you enter "25" and not "2" set it to == instead of Contains. Same goes for productname.
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public double Size { get; set; }
}
private List<Product> AddProducts()
{
List<Product> ProductList = new List<Product>();
var p = new Product();
p.Id = 1;
p.ProductName = "Product1";
p.Size = 25;
ProductList.Add(p);
var p2 = new Product();
p2.Id = 2;
p2.ProductName = "Product2";
p2.Size = 25;
ProductList.Add(p2);
return ProductList;
}
public ActionResult Index(string productname = "", string size = "")
{
var oProdList = from p in AddProducts() select p;
if (!string.IsNullOrWhiteSpace(productname) && !string.IsNullOrWhiteSpace(size))
{
oProdList = oProdList.Where(p => p.ProductName.ToUpper().Trim().Contains(productname.ToUpper().Trim()) && p.Size.ToString().Contains(size.Trim()));
}
else
{
oProdList = oProdList.Where(p => !string.IsNullOrWhiteSpace(productname) ? p.ProductName.ToUpper().Trim().Contains(productname.ToUpper().Trim()) : p.ProductName.ToUpper().Trim() == productname.ToUpper().Trim() || !string.IsNullOrWhiteSpace(size) ? p.Size.ToString().Contains(size.Trim()) : p.Size.ToString() == size.Trim());
}
ViewBag.ProductList = oProdList;
return View();
}

that happen because every string value contain string empty
and your parameter size default value set to string.empty
so you should check it for filtering the result like this
oProdList = oProdList.Where(
oProd =>(productname == string.Empty ? false:
oProd.ProductName.ToUpper().Contains(productname.ToUpper().Trim()))
|| (size == string.Empty ? false:oProd.Size.ToString().
ToUpper().Contains(size.ToUpper().Trim()))
);

I think the cause might be because of you are converting size to string
Try this
public ActionResult Index(string productname = "", string size = "0")
{
var oProdList = from ProdList in AddProducts() select oProdList;
oProdList = oProdList.Where(oProd => oProd.SectionName.ToUpper().Contains(ProductName.ToUpper().Trim())|| oProd.Size == (double)size));
ViewBag.ProductList = oProdList;
return View();
}

You can use the null coalescing operator here.
oProdList = oProdList.Where(oProd => (!String.IsNullOrEmpty((ProductName??"").Trim()) &&
oProd.ProductName.ToUpper().Contains(ProductName.ToUpper().Trim())
|| (!String.IsNullOrEmpty((size??"").Trim()) && oProd.Size.ToString().ToUpper().Contains(size.ToUpper().Trim())));

You need to specify to ignore search if the search params are empty.
Try this:
var productList = from ProdList in AddProducts()
where (productname.Trim() == string.Empty || ProdList.ProductName.ToUpper().Contains(ProductName.ToUpper().Trim()))
&& (size.Trim() == string.Empty || ProdList.Size.ToString().ToUpper().Contains(size.ToUpper().Trim()))
select ProdList;

if(!String.IsNullOrWhiteSpace(oProd.SectionName)){
oProdList = oProdList.Where(oProd => oProd.SectionName.ToUpper().Contains(ProductName.ToUpper().Trim());
}
if(!String.IsNullOrWhiteSpace(oProd.Size)){
oProdList = oProdList.Where(oProd => oProd.Size.ToUpper().Contains(size.ToUpper().Trim());
}

Related

Best Practice to find best matching instance in a List C#

For sure very simple question for most of you.
But I am struggling with a solution at the moment.
Imagine you have a list of cats (List) where each cat has a list of babys (Kitten)
public class Cat
{
public string Name { get; set; }
public int Age { get; set; }
public string Race { get; set; }
public bool Gender { get; set; }
public List<Kitten> Babys { get; set; }
}
public class Kitten
{
public string Name { get; set; }
public double Age { get; set; }
public bool Gender { get; set; }
}
now I want to find the Cat that has the most matches for given requirements. It could easily be the case that a cat matches only 2 of 3 requirements. I simple want to find the cat that has the most matches to my requirements.
where my requirements could be:
Name has to be "Micky"
Age is 42
Has a Kitten named "Mini"
My actual solution would be to compare all properties and take the one with the highest count of matching properties. But this is not generic and I am sure there are mutch better ways to do it.
Thanks in advance
Well, I have no opportunity to test this solution, but you can try this:
Assume that you have a list of cats:
var cats = new List<Cat>();
Now you have defined what are your criteria:
var desiredName = "Micky";
var desiredAge = 42;
var desiredKitten = "Mini";
And then you have to get your desired cat:
var desiredCat = cats
.Select(c => new {
Rating =
Convert.ToInt32(c.Age == desiredAge) + // Here you check first criteria
Convert.ToInt32(c.Name == desiredName) + // Check second
Convert.ToInt32(c.Babys.Count(b => b.Name == desiredKitten) > 0), // And the third one
c })
.OrderByDescending(obj => obj.Rating) // Here you order them by number of matching criteria
.Select(obj => obj.c) // Then you select only cats from your custom object
.First(); // And get the first of them
Please check if this works for you.
And if you need more specific answer or some edits for me to add.
If you really will compare 2 ou 3 requirements you can simplify using Linq by:
// try to find with 3 requirements
var foundCats = catList.Where(t => t.Name == desiredName &&
t.Age == desiredAge &&
t.Babys.Any(k => k.Name == desiredKitten)
).ToList();
if (foundCats.Any())
{
// you found the desired cat (or cats)
return foundCats;
}
// try to find with 2 requirements
foundCats = catList.Where(t =>
(t.Name == desiredName && t.Age == desiredAge) ||
(t.Name == desiredName && t.Babys.Any(k => k.Name == desiredKitten)) ||
(t.Age == desiredAge && t.Babys.Any(k => k.Name == desiredKitten)
).ToList();
if (foundCats.Any())
{
// you found the desired cat (or cats)
return foundCats;
}
// try to find with only 1 requirement
foundCats = catList.Where(t => t.Name == desiredName ||
t.Age == desiredAge ||
t.Babys.Any(k => k.Name == desiredKitten)
).ToList();
return foundCats;
So, I see that the problem is you don't know if in any near future you will have more properties, so I will suggest going to the hardway and make reflection, the following is ugly af but you can probably (you will) make it better and hopefully serves you well as guiadance:
public static List<Cat> CheckProperties(List<Cat> inCatList, Cat inQueryCat)
{
Dictionary<Cat, List<PropertyInfo>> dict = new Dictionary<Cat, List<PropertyInfo>>();
foreach (PropertyInfo pI in inQueryCat.GetType().GetProperties())
{
var value = pI.GetValue(inQueryCat);
if (value != null)
{
var cats = inCatList.Where(cat => cat.GetType().GetProperty(pI.Name).GetValue(cat).Equals(value));
foreach (Cat cat in cats)
{
if (dict.ContainsKey(cat))
{
dict[cat].Add(pI);
}
else
{
dict.Add(cat, new List<PropertyInfo>() {pI});
}
}
}
}
int max = Int32.MinValue;
foreach (KeyValuePair<Cat, List<PropertyInfo>> keyValuePair in dict)
{
if (keyValuePair.Value.Count > max)
{
max = keyValuePair.Value.Count;
}
}
return dict.Where(pair => pair.Value.Count == max).Select(pair => pair.Key).ToList();
}
While this is the most generic solution there is (need some edge case improvements):
public class ReflectCmpare
{
public PropertyInfo PropertyInfo { get; set; }
public dynamic Value { get; set; }
}
public Cat GetBestCat(List<Cat> listOfCats, List<ReflectCmpare> catParamsToCompare, List<ReflectCmpare> kittensParamsToCompare)
{
var bestScore = 0;
var ret = listOfCats[0];
foreach (var cat in listOfCats)
{
var score = catParamsToCompare.Sum(param => param.PropertyInfo.GetValue(cat, null) == param.Value ? 1 : 0);
foreach (var baby in cat.Babys)
{
score+= kittensParamsToCompare.Sum(param => param.PropertyInfo.GetValue(baby, null) == param.Value ? 1 : 0);
}
if (score <= bestScore) continue;
bestScore = score;
ret = cat;
}
return ret;
}
You should really think about just doing simple compare function
considering this objects is not dynamic this is the way to go:
public Cat GetBestCat(List<Cat> listOfCats, string name , int? age , bool? gender, string race ,string babyName,int? babyAge,bool? babyGender )
{
var ret = listOfCats[0];
var highestScore = 0;
foreach (var cat in listOfCats)
{
var score = 0;
score += name != null && cat.Name.Equals(name) ? 1 : 0;
score += age.HasValue && cat.Age.Equals(age.Value) ? 1 : 0;
score += gender.HasValue && cat.Gender.Equals(gender.Value) ? 1 : 0;
score += race != null && cat.Race.Equals(race) ? 1 : 0;
score += name != null && cat.Name.Equals(name) ? 1 : 0;
score += cat.Babys
.Where(k => babyName==null || k.Name.Equals(babyName))
.Where(k => !babyAge.HasValue || k.Age.Equals(babyAge.Value))
.Any(k => !babyGender.HasValue || k.Gender.Equals(babyGender.Value))?1:0;
if (score <= highestScore) continue;
highestScore = score;
ret = cat;
}
return ret;
}

Linq TotalCount of "Grandchildren" with null checks and property filters

Give the following classes:
[DebuggerDisplay("CustomerKey = {CustomerKey}")]
public class Customer
{
public Customer()
{
this.Orders = new List<Order>();
}
public int CustomerKey { get; set; }
public ICollection<Order> Orders { get; set; }
}
[DebuggerDisplay("OrderKey = {OrderKey}, OrderDateOffset='{OrderDateOffset}'")]
public class Order
{
public Order()
{
this.OrderDetails = new List<OrderDetail>();
}
public int OrderKey { get; set; }
public Customer ParentCustomer { get; set; }
public DateTimeOffset OrderDateOffset { get; set; }
public ICollection<OrderDetail> OrderDetails { get; set; }
}
[DebuggerDisplay("OrderDetailKey='{OrderDetailKey}', ProductKey='{ProductKey}', Quantity='{Quantity}', UnitPrice='{UnitPrice}, BackOrdered='{BackOrdered}'")]
public class OrderDetail
{
public int OrderDetailKey { get; set; }
public Order ParentOrder { get; set; }
public int ProductKey { get; set; }
public int Quantity { get; set; }
public Decimal UnitPrice { get; set; }
public bool BackOrdered { get; set; }
}
Given the following hydration:
ICollection<Customer> customers = new List<Customer>();
Customer customerOne = new Customer() { CustomerKey = 11111 };
/**/
Order orderOne = null;
customerOne.Orders.Add(orderOne);/* note, the item added to the collection is null) */
/**/
Order orderTwo = new Order() { OrderKey = 22222, OrderDateOffset = DateTimeOffset.Now };
orderTwo.OrderDetails = null;/* Note, the child collection is null */
customerOne.Orders.Add(orderTwo);
/**/
Order orderThree = new Order() { OrderKey = 22223, OrderDateOffset = DateTimeOffset.Now };
orderThree.OrderDetails.Add(null); /* note, the item added to the collection is null) */
customerOne.Orders.Add(orderThree);
/**/
Order orderFour = new Order() { OrderKey = 22221, OrderDateOffset = DateTimeOffset.Now };
orderFour.OrderDetails.Add(new OrderDetail() { OrderDetailKey = 33333, ProductKey = 11, Quantity = 1, UnitPrice = 1M, BackOrdered = false });
orderFour.OrderDetails.Add(new OrderDetail() { OrderDetailKey = 33334, ProductKey = 12, Quantity = 2, UnitPrice = 2M, BackOrdered = false });
orderFour.OrderDetails.Add(new OrderDetail() { OrderDetailKey = 33335, ProductKey = 13, Quantity = 3, UnitPrice = 3M, BackOrdered = true });
customerOne.Orders.Add(orderFour);
customers.Add(customerOne);
customers.Add(null);/* note, the item added to the collection is null) */
I'm trying to get a total count of all back-ordered OrderDetail(s).
My pre-linq code :
int totalBackOrderedCount = 0;
if (null != customers)
{
foreach (Customer cust in customers)
{
if (null != cust)
{
if (null != cust.Orders)
{
foreach (Order ord in cust.Orders)
{
if (null != ord)
{
if (null != ord.OrderDetails)
{
foreach (OrderDetail ordDet in ord.OrderDetails)
{
if (null != ordDet)
{
if (ordDet.BackOrdered)
{
totalBackOrderedCount++;
}
}
else
{
Console.WriteLine("ordDet was null, good thing I coded for it");
}
}
}
else
{
Console.WriteLine("ord.OrderDetails was null, good thing I coded for it");
}
}
else
{
Console.WriteLine("ord was null, good thing I coded for it");
}
}
}
}
else
{
Console.WriteLine("cust was null, good thing I coded for it");
}
}
}
Console.WriteLine("totalBackOrderedCount={0}", totalBackOrderedCount);
My attempt(s) at a linq alternative:
int linqyTotalBackOrderedCountOne =
(
from cust in customers
from ord in (cust.Orders ?? Enumerable.Empty<Order>()).DefaultIfEmpty()
from ordDet in (ord.OrderDetails.Where(od => od.BackOrdered == true) ?? Enumerable.Empty<OrderDetail>()).DefaultIfEmpty()
where cust != null && (null != ord) && (null != ordDet)
select ordDet
).Count();
int linqyTotalBackOrderedCountTwo =
(
from cust in customers
from ord in (cust.Orders ?? Enumerable.Empty<Order>()).DefaultIfEmpty()
from ordDet in (ord.OrderDetails.Where(od => od.BackOrdered == true) ?? Enumerable.Empty<OrderDetail>()).DefaultIfEmpty()
where cust != null && (null!=cust.Orders) && (null!=ord) && (null!=ord.OrderDetails) && (null!=ordDet)
select ordDet
).Count();
Is there a "null friendly" way in linq to get children of children ... ?
You should be able to do something like this without needing to worry about nulls.
var count = customers.Where (c => c.Orders != null)
.SelectMany (c => c.Orders.Where(o => o.OrderDetails != null)
.SelectMany (o => o.OrderDetails))
.Count (c => c.BackOrdered);
The above was close...here is the final answer:
int itWorksCount = customers.Where(c => null != c && null != c.Orders)
.SelectMany(c => c.Orders.Where(o => null != o && null != o.OrderDetails)
.SelectMany(o => o.OrderDetails.Where(ordDet => null != ordDet)))
.Count(c => c.BackOrdered);
Do not have ICollection<T> properties be null. There is absolutely no reason to have null values in there, when you can also have an empty collection (which you instantiate in the constructor even, so you are not saving memory).
Redesign your Customer and Order classes so that the setter of the Orders and OrderDetails property is private. Your serialization should be able to handle this (Entity Framework / NHibernate / Data Contracts do at least). This prevents other code from setting the collection to null.
Also, why do you allow inserting null values into the collections? What does the null value represent. Is there an unfilled order, a placeholder for something? If that is the case, put in some value that represents a missing order / order detail.
After fixing your design, use Gary. S's original answer:
int count = customers.SelectMany(c => c.Orders)
.SelectMany(o => o.OrderDetails)
.Count(od => od.BackOrdered);
Note, there is always a null friendly way to do everything, but it makes code overly complex and hard to maintain.

Compare two lists - If any objects property in one list have changed or a new object in list been added, return that object

Let's say I have this class:
public class Product
{
public string Id { get; set; }
public int Quantity { get; set; }
}
Then I have two lists of these:
var oldList = new List<Product>(){
new Product(){
Id = "1", Quantity = 1
}
};
var newList = new List<Product>(){
new Product(){
Id = "1", Quantity = 5
}
};
How can I compare these two list and return a single Product-object of the item in the newList that have changed. Like the code-scenario above I want to return a Product-object with the values Id = "1", Quantity = 5
The other scenario looks like this:
var oldList = new List<Product>(){
new Product(){
Id = "1", Quantity = 1
}
};
var newList = new List<Product>(){
new Product(){
Id = "1", Quantity = 1
},
new Product(){
Id = "2", Quantity = 1
}
};
If a new item been added to the newList then I want to return that item(product-object with Id="2")
You could try something like this:
var result = newList.Except(oldList);
but you have first to implement the IEquatable interface for the Product class.
public class Product : IEquatable<Product>
{
public string Id { get; set; }
public int Quantity { get; set; }
public bool Equals(Product product)
{
if (product == null)
{
return false;
}
return (Id == product.Id) && (Quantity == product.Quantity);
}
}
First you should implement equality comparer to compare that 2 product items are equal:
class ProductEqualityComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.Id == y.Id && x.Quantity == y.Quantity;
}
public int GetHashCode(Product product)
{
if (Object.ReferenceEquals(product, null)) return 0;
return product.Id.GetHashCode() ^ product.Quantity.GetHashCode();
}
}
Then you can use Except function to get the difference between 2 lists:
var result = newList.Except(oldList, new ProductEqualityComparer() );
A workaround, so you dont have to use Except is to do it using Linq to Object like this:
public List<MyItems> GetItemsFromANotInThatAreNotInB(List<MyItems> A, List<MyItems> B)
{
return (from b in B
where !(from a in A select a.Id).Contains(b.Id)
select b).ToList();
}

c# class object filtering

I have sucha a situation. I have list inside which I am holding objects of one class (this objects has 6 properties "Name", "Type", "Index", "Value", "Status", "Parameter"). Later I am binding it with gridView.
Now I would like to be able to make a filter for each of this properties. I want to be able for example to insert into textbox "Name" : John, and I would like gridView to display only rows where I have John.
Second thing is that I would like to be able to mix filters, so have for example "Name" set to : 'John' and "Index" to : 5, and display "John" with "Index" : 5.
How can I do this?
Now I only have function to insert everything into list. This objects are stored inside Middle property of class WholeLine.
Correction method = new Correction();
while ((line = sr.ReadLine()) != null)
{
string[] _columns = line.Split(",".ToCharArray());
object returnValue;
MyColumns mc = new MyColumns();
mc.Time = _columns[0];
mc.Information = _columns[1];
mc.Description = _columns[2];
if (String.IsNullOrEmpty(mc.Information) )
{ continue; }
else
{
returnValue = method.HandleRegex(mc.Information);
}
Line main = new Line();
main.LeftColumn = mc.Time;
main.Middle= returnValue;
main.RightColumn = mc.Description;
list3.Add(main);
}
EDIT:
It is not that simple in my situation (I think...), because I have main class where I have this while shown above. Later I call method HadleRegex from class Correction . Bellow I will show how it looks like:
class Correction
{
private MoreInfor _MoreInfor = new MoreInfor();
public MoreInfor MoreInfor { get { return _ID; } }
Correction sk = new Correction();
Match matches = Regex.Match(newStr, #"\b(?:complete\b)", RegexOptions.IgnoreCase);
if (matches.Success)
{
string[] lines = newStr.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
Regex regex1 = new Regex(#"^(?:(?<C0>Command) (?:answer|sent) from (?<C1>\S+) to (?<C2>\S+) (?<C3>.+))$");
var matches1 = lines.Select(line => regex1.Match(line));
foreach (var match in matches1)
{
sk._MoreInfor.Name= match.Groups["C1"].ToString();
sk._MoreInfor.Type = match.Groups["C2"].ToString();
sk._MoreInfor.Value = match.Groups["C3"].ToString();
sk._MoreInfor.Index = match.Groups["C4"].ToString();
}
}
return sk;
}
public class MoreInfo
{
public string Name{ get; set; }
public string Type { get; set; }
public string Index { get; set; }
public string Value { get; set; }
public string Status { get; set; }
public string Parameter { get; set; }
}
This returned vale of class Correction is later passed to returnValue from my main class and added to Middle property of class Line
I'm sorry if I really messed up!
You can use linq - where
var result = list.Where(x => x.Name == textBoxName.Text).ToList();
This assumes your textbox will search for a name
For multiple filters,
list.Where(x => x.Property == "something" && x.Name == textBoxName.Text).ToList();
list.Where(x => result.Where(ix => x.Property == "something").ToList();
You may define some "NoFilter" values. For instance index may be -1, or Name = ""
public List<person> FilterPersons (List<person> persons,
string name = "",
string type = "",
int index = -1,
int value = -1,
int status = -1,
string parameter = "")
{
return persons
.Where
(
x=>
(name == "" || x.Name == name)
&& (type == "" || x.Type == type)
&& (index == -1 || x.Index == index)
&& (value == -1 || x.Value == value)
&& (status == -1 || x.Status == status)
&& (parameter == "" || x.Parameter == parameter)
)
.Select(x=>x);
}
And then you may call it as:
filterPersons = FilterPersons(persons: persons,name: "John");
or
filterPersons = FilterPersons(persons: persons,index: 10, status: 5);
use linq to filer
yourlist.Select(x=>x.Name == "John");

How do I match two identical database tables with LINQ?

I want to match 2 identical tables:
sourceProducts (productName, ProductionDate, ManID, shipper, distributer)
CommProducts (productName, ProductionDate, ManID, shipper, distributer)
but the number of rows and the record contents may differ. How do I select a certain record = raw from one table and get its clone record from the other table (e.g., check if the same record exists)? How do I do this using LinQ?
UPDATE: Here's the LINQ code:
protected void checkBtn_Click(object sender, EventArgs e)
{
MyProductsDataContext mySdb = new MyProductsDataContext();
Product mypro = new Product { ManId = int.Parse(TxtManI.Text), ProductName = TxtProN.Text, ProductionDate =DateTime .Parse ( TxtProDat.Text), Shipper = TxtShipI.Text, Distributer = TxtDistI.Text };
var spro = (from p in mySdb.Products
select new { p.ManId, p.ProductName, p.ProductionDate, p.Shipper, p.Distributer }).
Intersect(from s in mySdb.SourceProducts select new { s.ManId, s.ProductName, s.ProductionDate, s.Shipper, s.Distributer });
if (spro != null)
{
LblMessage.Text = "Acceptable product Data Inserted Sucessfully";
InsertData();
}
else
{
LblMessage.Text = "Invalid Product or bad Entry Please retype";
}
}
I would join on ManId and then compare the rest of the values in a where clause:
bool productExists = (
from p in mySdb.Products
join s in mySdb.SourceProducts
on p.ManId equals s.ManId
where p.ProductName == s.ProductName
&& p.ProductionDate == s.ProductionDate
&& p.Shipper == s.Shipper
&& p.Distributer = s.Distributer
select new { p.ManId, p.ProductName, p.ProductionDate, p.Shipper, p.Distributer }
).Any();
if (productExists)
{
LblMessage.Text = "Acceptable product Data Inserted Sucessfully";
InsertData();
}
else
{
LblMessage.Text = "Invalid Product or bad Entry Please retype";
}
I've used Any() to produce an efficient EXISTS SQL query. You could use SingleOrDefault() or FirstOrDefault() instead if you actually need to use the product returned.
I also don't see anywhere that you're using your new Product's ID - you might need to add that filter to the query as well:
Product mypro = new Product { ... };
bool productExists = (
from p in mySdb.Products
where p.ManId equals mypro.ManId
join s in mySdb.SourceProducts
on p.ManId equals s.ManId
...
You can probably do this using a join but I've hobbled together a unit test which shows one way to this
public class TestProduct
{
public int ManId { get; set; }
public string ProductName { get; set; }
public DateTime ProductionDate { get; set; }
public string Shipper { get; set; }
public string Distributor { get; set; }
}
[TestMethod]
public void TestSourceTable()
{
// Set up a test list
var list = new List<TestProduct>();
for (int i=0;i<5;i++)
{
var p = new TestProduct
{
Distributor = "D" + i,
ManId = i,
ProductionDate = DateTime.Now,
ProductName = "P" + i,
Shipper = "S" + i
};
list.Add(p);
}
// Get an existing product
var existingProduct = list[4];
// Get an unknown product
var unknownProduct = new TestProduct()
{
ManId = -1,
Distributor = "",
ProductionDate = DateTime.Now.AddDays(-1),
ProductName = "",
Shipper = ""
};
// product found
Assert.True(list.Any(p => p == existingProduct));
// product not found
Assert.False(list.Any(p => p == unknownProduct));
}

Categories

Resources