problem with delete when multiple columns - linq

when deleteing this works:
orderitems.Delete(x => x.orderitem_sessionid == transkey);
however this does not work
orderitem.Delete(x => x.orderitem_sessionid == transkey
&& x.orderitem_productid == 6);
i get no errors, but nothing is deleted either, i have working code as a substitute of
var DeleteableItems = orderitems.All().where(x => x.orderitem_sessionid == transkey
&& x.orderitem_productid = 6);
foreach(var item in DeleteableItems) item.delete;
though the above works it still bugs me that this wont work with just nomal delete method, using subsonic 3.0.0.3 and mysql database
thanks

Have you tried:
orderitem.Delete(x => x.orderitem_sessionid == transkey
&& x.orderitem_productid == 6);
The last operator in your version is assignment not comparisson.
My answer concerned a typo but the comments on getting the generated SQL below some might find useful.
Kindness,
Dan

Related

Exclude elements that appear in another sequence

I have the following sequence:
public static List<string> IgnoredSubCodes => new List<string> {"HERE", "NOT_HERE"};
var demographics = personify.CUS_DEMOGRAPHIC.Where(demographic =>
clubIds.Contains(demographic.MASTER_CUSTOMER_ID) &&
distinctCodes.Contains(demographic.DEMOGRAPHIC_CODE) &&
distinctProgramYears.Contains(demographic.USR_PROGRAM_YEAR) &&
!demographic.DEMOGRAPHIC_SUBCODE.Any(x => PersonifyConstants.DemographicCodes.DemographicSubCodes.IgnoredSubCodes));
The last line above won't work but I'd like to be able to say "don't include any demographic subcode that appears in this list". How can I do that? I've tried a couple of different clauses with .Where and .Any but I'm not understanding the permutation I need. I could hardcode it inside that query as demographic.DEMOGRAPHIC_SUBCODE != "HERE" && demographic.DEMOGRAPHIC_SUBCODE != "NOT_HERE" but I'd like to have all the exclusions in one place.
Could you try this? Hope it will work.
var demographics = personify.CUS_DEMOGRAPHIC.Where(demographic =>
clubIds.Contains(demographic.MASTER_CUSTOMER_ID) &&
distinctCodes.Contains(demographic.DEMOGRAPHIC_CODE) &&
distinctProgramYears.Contains(demographic.USR_PROGRAM_YEAR) &&
!PersonifyConstants.DemographicCodes.DemographicSubCodes.IgnoredSubCodes.Any(code => code == demographic.DEMOGRAPHIC_SUBCODE));

Why is LINQ query to DataTable not working?

I have a DataTable, dt, that contains the following:
As you can see, there are two sets of files here: baseline (columns 1-3) and target (columns 4-6). So in this case I have 4 baseline files, m4, m5, m1, and m3 (m1 in row 5 is copied from row 3) and one target file, m1. The problem is that the information for the baseline file m1.txt is duplicated, so I'm trying to remove it using the following LINQ statement:
var extraneousRows = dt.Rows.Cast<DataRow>().
Where(
row => row["BASELINE_FOLDER"] == baselineSubfolder
&& row["BASELINE_FILE"] == baselineFilename
&& row["BASELINE_CHECKSUM"] == baselineChecksum
&& row["STATUS"] == "remove"
).ToArray();
foreach (DataRow dr in extraneousRows)
{
dt.Rows.Remove(dr);
}
This should remove the 3rd row from the DataTable but it doesn't. The code works fine if I omit the && row["STATUS"] == "remove" line, so I know it's functional. And the values for baselineSubfolder, baselineFilename, and baselineChecksum are correct, so that's not the problem.
But for some reason, when I include that line about the status column, it doesn't detect that that row is in the DataTable, even though it clearly is according to the DataSet Visualizer (photo above). So it's never entering the foreach loop and not removing the necessary files. Why???
I maybe should mention that the baseline file information (first 4 rows) are being retrieved from a database, whereas the target file fields are being generated according to user input. I don't see how it would matter where the information is coming from, though, since I'm querying the DataTable directly...
UPDATE
Ok, after following the suggestions of idipous and Jamie Keeling, I've determined that the problem had to do with the foreach loop, which was never being populated. Since this query should only ever return a single row, I eliminated the loop altogether. My revised code looks like this:
var extraneousRows = dt.Rows.Cast<DataRow>().
Where(
row => row["BASELINE_FOLDER"] == baselineSubfolder
&& row["BASELINE_FILE"] == baselineFilename
&& row["BASELINE_CHECKSUM"] == baselineChecksum
&& row["STATUS"] == "remove"
).SingleOrDefault();
dt.Rows.Remove(extraneousRows);
For whatever reason, extraneousRows remains null and that last line is generating a runtime error: IndexOutOfRangeException: The given DataRow is not in the current DataRowCollection
Why isn't this working?
It actually turns out that the problem was that I needed to cast the column values to strings. The solution was incredibly simple: just add a .ToString() after the column names and viola! The following code worked like a charm:
var extraneousRows = dt.Rows.Cast<DataRow>().
Where(
row => row["BASELINE_FOLDER"].ToString() == baselineSubfolder
&& row["BASELINE_FILE"].ToString() == baselineFilename
&& row["BASELINE_CHECKSUM"].ToString() == baselineChecksum
&& row["STATUS"].ToString() == "remove"
).SingleOrDefault();
dt.Rows.Remove(extraneousRows);
I also found a non-LINQ way to do this, by iterating through all the rows of the DataTable. It's not the most efficient, but it works:
for (int z = 0; z < dt.Rows.Count; z++)
{
if ((dt.Rows[z]["BASELINE_FOLDER"].ToString() == baselineSubfolder)
&& (dt.Rows[z]["BASELINE_FILE"].ToString() == baselineFilename)
&& (dt.Rows[z]["BASELINE_CHECKSUM"].ToString() == baselineChecksum)
&& (dt.Rows[z]["STATUS"].ToString() == "remove"))
{
dt.Rows[z].Delete();
}
}
dt.AcceptChanges();

linq filtering child collection

I have read over a bunch of different topics on this, but i havent found what I am looking for.
I have an EF query that is this:
var query = this.ObjectContext.Questions
.Include("AnswerKey").Include("QuestionTypes")
.Where(o => o.SurveyQuestions.Any(o2 => o2.SurveyID == id));
This was working fine until i realized that i was not taking into account my Active Flag for the AnswerKey child collection. In other words, this query should load all questions that have a parent surveyid of 3(which it does)but only load AnswerKeys that have an active flag of true.
I have tried this:
var query = this.ObjectContext.AnswerKey
.Include("Questions.QuestionTypes")
.Where(ak =>
ak.Active == true &&
ak.Questions.SurveyQuestions.Any(sq => sq.SurveyID == 3) &&
ak.Questions.Active == true)
.AsEnumerable()
.Select(ak => ak.Questions).AsQueryable();
But it returns 1 question for each answerkey. So if a question has 4 answer it shows up 4 times...
How can i do this?
You could just use Distinct() at the end to filter out the duplicates:
.AsEnumerable()
.Select(ak => ak.Questions)
.Distinct()
.AsQueryable();
Brokenglass I will try your suggestion. And give you the credit if it works..
I also found this here after following another link on SO... and this appears to work as well but i need to verify it in my app.

How to convert a LINQ query from query syntax to query method

Linq and EF4.
I have this Linq query in query syntax I would like convert into query method.
Are you able to do it? I tried more tha 2 hours without success :-(
Thanks for your time
CmsContent myContentObj = (from cnt in context.CmsContents
from categoy in cnt.CmsCategories
where categoy.CategoryId == myCurrentCategoryId && cnt.ContentId == myCurrentContentId
select cnt).Single();
My original answer selected the wrong item. It's a bit more complicated than what I had (which Ani has posted). Here's what I believe is an equivalent query however and should perform better:
CmsContent myContentObj =
context.CmsContents
.Where(cnt => cnt.ContentId == myCurrentId
&& cnt.CmsCategories
.Any(categoy => categoy.CategoryId == myCurrentCategoryId))
.Single();
Here is a non-direct translation that I believe performs the same task in much less code:
var myContentObj = context.CmsContents.Single(
x => x.ContentId == myCurrentContentId &&
x.CmsCategories.Any(y => y.CategoryId == myCurrentCategoryId)
);
Here's how the C# compiler actually does it, with some help from .NET Reflector to verify:
var myContentObj = context
.CmsContents
.SelectMany(cnt => cnt.CmsCategories,
(cnt, categoy) => new { cnt, categoy })
.Where(a => a.categoy.CategoryId == myCurrentCategoryId
&& a.cnt.ContentId == myCurrentContentId)
.Select(a => a.cnt)
.Single();
Essentially, the 'nested' from clauses results in a SelectMany call with a transparent identifier (an anonymous-type instance holding the 'parent' cnt and the 'child' categoy). The Where filter is applied on the anonymous-type instance, and then we do another Select projection to get back the 'parent'. The Single call was always 'outside' the query expression of course, so it should be obvious how that fits in.
For more information, I suggest reading Jon Skeet's article How query expressions work.

Linq check to see is there any NULLs in a set of DataRows?

I have a set DataRows and I want to check if any of the fields in any of those rows has a NULL value in it. I came up with this below, but I'm not sure because I'm nesting an ALL.
result.AsEnumerable().AsQueryable().All(o => o.ItemArray.All(i=>i == DBNull.Value))
Hard to tell because I can't put a "watch" in lambdas.
Actually you need to use Any (in your code you will return true if All values are null) and AsQueryable() is useless in this case.
bool nullFound = result.AsEnumerable()
.Any(o => o.ItemArray.Any(i=>i == DBNull.Value || i == null));
Then, If you need a list of all rows with some value null, just do the following:
var rowsWithNulls = result.AsEnumerable()
.Where(o => o.ItemArray.Any(i=>i == DBNull.Value || i == null))
.ToList();
P.S.
I also added a null check to be more safe, but if you are sure to have only DBNull.Value, you can remove it.
Not sure if this is the correct answer. I'm also rather new to Linq, but i believe you can do something like this;
result.AsEnumerable().AsQueryable().SingleOrDefault(o => o.ItemArray.All(i=>i == DBNull.Value))
This will return an list of items or null if there aren't any. Not sure if you can also nest it, but don't see why it wouldn't be possible

Resources