Problem with selecting rows from msi file - c#

I wrote a config tool to easily configure msi installers I create with a Visual Studio Setup project. I successfully edited entries in the InstallExecuteSequence table. Now I would like the change something in the Control table as well but the select query returns 0 entries.
using (Database db = new Database(path, DatabaseOpenMode.Transact))
{
using (var vw = db.OpenView(db.Tables["Control"].SqlSelectString))
{
vw.Execute();
Record record = vw.Fetch(); // <= this always returns null
while (record != null)
{
record = vw.Fetch();
if (record == null)
break;
if (record["Dialog_"].ToString().ToLower().Contains("CustomCheckA") && record["Control"].ToString().ToLower().Contains("Text"))
{
tbName.Text = record["Text"].ToString();
}
if (record["Dialog_"].ToString().ToLower().Contains("CustomCheckA") && record["Control"].ToString().ToLower().Contains("BodyText"))
{
tbDescription.Text = record["Text"].ToString();
}
}
if (String.IsNullOrEmpty(eintrag.IDString))
MessageBox.Show("This file does not contain the searched keywords");
vw.Close();
}
db.Close();
}

I believe you need to add more information of the result you want, but I see something here.
if (record["Dialog_"].ToString().ToLower().Contains("CustomCheckA")
You are converting it to lower and then checking if contains that word, but the word is not all lowercase. So the result is always false.

Related

check if item contain in list

I have a list of installed programs
With Debug.writeLine I can see in the output that there is a discord item.
result.PackageName It can be Discrod, Discord PTB or Discord Canary.
foreach (var installedItem in _installedApps)
{
if (installedItem.DisplayName.Contains("Discord"))
{
Debug.WriteLine(installedItem.DisplayName);
Debug.WriteLine(result.PackageName);
}
if (installedItem.DisplayName.Trim().Contains(result.PackageName.Trim()))
{
isInstalled = true;
}
else
{
isInstalled = false;
}
}
But the code does not work and always returns false
UPDATE:
If I use the following code
var installedStatus = _installedApps.Where(x => x.DisplayName != null && result.PackageName != null && x.DisplayName.Contains(result.PackageName, StringComparison.OrdinalIgnoreCase)).Any();
And in the list of _installedApps, there is only one item named Discord PTB And also in the loop, which is the PackageName Discrod, Discrod PTB or Discrod Canary.
I have a false report that both versions are installed Only PTB should have an installation report.
But if I use the following code
var installedStatus = _installedApps.Where(x => x.DisplayName != null && result.PackageName != null && result.PackageName.Contains(x.DisplayName, StringComparison.OrdinalIgnoreCase)).Select(x => x.Version);
I have the correct report, but the problem is that other programs are not detected
This is not working because isInstalled is getting set by ever iteration.
So the last installedItem can set the value to false.
in essence this is isInstalled is only relevant to the last item.
If you want to use this code just remove the else.
if you want to use linq i would do it like this
isInstalled = _installedApps.Any(i=>i.DisplayName.Trim().Contains(result.PackageName.Trim()))

Run if condition if data not exists

Please check code bellow. I am having wrong entity query i think. check inside second if condition and marked entity query. My goal is save data if this CategoryID not available. But when i run it on debug i can see simply the if condition being skipped however my database not has any data so it should be empty and run if inside codes. I think i am doing something wrong with entity query which marked bellow. Any idea?
ctx.Level1Cats.Any(x => x.Level1CatId != item.CategoryID.ToString())
foreach (CategoryType item in categories)
{
if (item.CategoryLevel == 1)
{
if (ctx.Level1Cats.Any(x => x.Level1CatId != item.CategoryID.ToString()))
{
CatLevel1.Level1CatId = item.CategoryID;
CatLevel1.Name = item.CategoryName;
ctx.Level1Cats.Add(CatLevel1);
//ctx.SaveChanges();
}
else if (ctx.Level1Cats.Any(x => x.Level1CatId == item.CategoryID.ToString()))
{
CatLevel1.Level1CatId = item.CategoryID;
CatLevel1.Name = item.CategoryName;
ctx.Entry(CatLevel1).State = EntityState.Modified;
ctx.SaveChanges();
}
}
}
To solve your problem using your existing code, you can use All inside of the if and then just use a standard else without the additional check:
if (ctx.Level1Cats.All(x => x.Level1CatId != item.CategoryID.ToString()))
{
...
}
else
{
...
}
This will go into your if block if item.CategoryID does not exist (note that All returns true if the list itself is empty). Otherwise, your else will be used instead.
Another option would be to keep the Any but invert the logic:
if (ctx.Level1Cats.Any(x => x.Level1CatId == item.CategoryID.ToString()))
{
// UPDATE.
}
else
{
// ADD.
}
In this case, if any of the items matches the item.CategoryID, you will peform your update. Otherwise, it'll be the Add.
In my experience, the second option shown is more common, where you're looking specifically to find the item of interest and then reacting accordingly.

Does EntityFramework Monitor variables prior to it's declaration and use?

I couldn't understand what was happening when I use Linq.Any() method to check if object contains a specific value, the code throws a NullReferenceException on variable with data prior it's use.
The code below:
public ML.Order FetchOrder(ML.MLDBContext db, long OrderID)
{
if (db == null)
db = new ML.MLDBContext();
//avoided code to fetch the Order details from another system via API
Order apiOrder = api.OrdersGet(OrderID);
//avoided code to test null results
bool isNew = false; //to check if fetched order is new or must be updated on DB
//load from DB
ML.Order dbOrder = db.Orders.Where(o => o.OrderID == apiOrder.id).FirstOrDefault();
if (dbOrder == null)
{
isNew = true;
//avoided code to fill dbOrder with apiOrder data
//Below code check if user bought the same product before
//the error is thrown here but it's not null
string ListingID = apiOrder.order_items.First().item.id;
var previousOrders = db.Orders.Where(order => order.OrderID != apiOrder.id && order.CustomerID == apiOrder.buyer.id && order.SellerID == apiOrder.seller.id).ToList();
foreach (ML.Order prevOrder in previousOrders)
{
if (prevOrder.OrderedItems.Any(i => i.ListingID == ListingID)) //Line who causes the error
{
//code to mask as reordered item
}
}
Some points:
I'm sure "apiOrder.order_items.First().item.id" always have any value.
I'm sure the Order contains the item I'm looking for and the field isn't nullable.
When I comment the line who causes the error, the debug will pass through without errors
To solve this problem, I had to replace Linq.Any() by foreach
foreach (ML.Order prevOrder in previousOrders)
{
foreach (ML.OrderedItem item in prevOrder.OrderedItems)
{
if (item.ListingID == ListingID)
{
//code to mask as reordered item
}
}
}
My doubt is:
Does Linq.Any() or EntityFramework Monitor variables prior to it's declaration and use?
Why the NullreferenceException was trowed on variable prior it usage?
What's the problem using the Linq.Any() method to check the existence of a value inside EF object?

Add to exisiting Database instance from MVC Controller

Private BookingDB db = new BookingDB();
Private MonthDb mdb = new MonthDB();
if (ModelState.IsValid)
{
String date = (booking.Start_Date).ToString();
var check = from b in mdb.months
where b.BookedDays.Contains(date)
select b;
if (check != null)
{
return View(booking);
}
else
{
booking.Reservation_Owner = User.Identity.Name;
//Add booking.Start_Date to mdb.Entry(check).BookedDays
mdb.SaveChanges();
db.bookings.Add(booking);
db.SaveChanges();
return RedirectToAction("Index");
}
}
I've got this code that on creation of a new booking, will check that no exisiting bookings have already been made on or around that specific day.
if the day to be booked is not already been booked (ie exists under BookedDays in mdb.months) then i wish to add the Start_Date of the booking, to the BookedDays string in the mdb.months database (the mdb.month database is just a list of the 12 months)
at first i tried using mdb.Entry() to add to that specific month instance, however i cannot get it to work.
the error is:
the model does not have a definition for BookedDays
what do?
Your checking that check is null
if (check != null)
{
return View(booking);
}
else
{
and then using check anyway:
check.BookedDays
check is null and therefore does not contain any BookedDays. I'm guessing your null check is the wrong way around and should be
if (check == null)
{
return View(booking);
}
else
{
That said your problem is not well explained so I'm not sure.

Entity framework inserts wrong entity into db on savechanges

I am trying to write a program to scan a directory containing tv show folders, look up some details about the shows using tvrage API and then save the details to a database using entity framework.
My TVShow table pkey is the same value as taken from the tvrage database show id, and I am having issues when duplicate or similar folder names are returning the same Show info. In a situation where I have a directory containing three folders, "Alias", "Alias 1" , "Band of Brothers" I get the following output from my code
* TV SHOWS *
Alias....... NO MATCH......ADDING........DONE
Alias 1 ...... NO MATCH.....ADDING....CANT ADD, ID ALREADY EXISTS IN DB
Band of Brothers ...... NO MATCH..ADDING....
Before getting an UpdateException on the context.SaveChanges(); line
Violation of PRIMARY KEY constraint 'PK_TVShows'.
I can see using SQL profiler that the problem is that my app is trying to perform an insert on the alias show for a second time with duplicate key, but I can't see why. When I step through the code on the second interaction of the foreach loop (second "alias" folder), the code to save the show entity to the database is bypassed.
It is only on the next iteration of the foreach loop when I have created a new TVShow entity for "Band of Brothers" do I
actually reach the code which adds a Tvshow to context and saves, at which point the app crashes. In visual studio I can see
at the point of the crash that;
"show" entity in context.TVShows.AddObject(show) is "Band of Brothers" w/ a unique ID
context.TVShows only contains one record, the first Alias Entity
But SQL profiler shows that EntityFramework is instead inserting Alias for a second time, and I am stumped by why this is
private void ScanForTVShowFolders( GenreDirectoryInfo drive ) {
IEnumerable<DirectoryInfo> shows = drive.DirInfo.EnumerateDirectories();
foreach (DirectoryInfo d in shows) {
//showList contains a list of existing TV show names previously queried out of DB
if (showList.Contains(d.Name)) {
System.Console.WriteLine(d.Name + ".....MATCH");
} else {
System.Console.Write(d.Name + "......NO MATCH..ADDING....");
TVShow show = LookUpShowOnline(d.Name, drive.GenreName);
if (show.Id == -1) { // id of -1 means online search failed
System.Console.Write("..........CANT FIND SHOW" + Environment.NewLine);
} else if (context.TVShows.Any(a => a.Id == show.Id)) { //catch duplicate primary key insert
System.Console.Write(".......CANT ADD, ID ALREADY EXISTS IN DB" + Environment.NewLine);
} else {
context.TVShows.AddObject(show);
context.SaveChanges();
System.Console.Write("....DONE" + Environment.NewLine);
}
}
}
private TVShow LookUpShowOnline( string name, string genre ) {
string xmlPath = String.Format("http://services.tvrage.com/feeds/search.php?show='{0}'", name);
TVShow aShow = new TVShow();
aShow.Id = -1; // -1 = Can't find
XmlDocument xmlResp = new XmlDocument();
try { xmlResp.Load(xmlPath); } catch (WebException e) { System.Console.WriteLine(e); }
XmlNode root = xmlResp.FirstChild;
if (root.NodeType == XmlNodeType.XmlDeclaration) { root = root.NextSibling; }
XmlNode tvShowXML;
//if (showXML["episode"] == null)
// return false;
tvShowXML = root["show"];
if (tvShowXML != null) {
aShow.Id = System.Convert.ToInt16(tvShowXML["showid"].InnerText);
aShow.Name = tvShowXML["name"].InnerText.Trim();
aShow.StartYear = tvShowXML["started"].InnerText.Trim();
aShow.Status = tvShowXML["status"].InnerText.Trim();
aShow.TVGenre = context.TVGenres.Where(b => b.Name.Trim() == genre).Single();
}
return aShow;
}
}
Edit
Doing some more reading I added context.ObjectStateManager to my debug watchlist and I can see everytime I create a new TVShow entity a new record is added to _addedEntityStore. Actually if I remove context.TVShows.AddObject(show) the code still updates the database so manually adding to the context seems redundant.
If your are inserting object by foreach loop > better to keep the Primary Key outside and make it increment!
eg: int newID= Shows.Select(d=>d.Id).Max();
foreach(............)
{
show.Id = newID++;
.
.
. //remaining fields
.
context.TVShows.AddObject(show);
}
context.SaveChanges();
it works for me...!!
Turns out context.TVShows.AddObject(show) is unnecessary in my case, I was inadvertently adding all created show entities to the context when this query runs
aShow.TVGenre = context.TVGenres.Where(b => b.Name.Trim() == genre).Single();
This is not what I wanted, I just wanted to create the object, then decide whether to add it. Will be pretty easy to fix now I know why it's happening.

Categories

Resources