Invalid update expression exception in EntityFramework Extensions UpdateFromQuery - entity-framework-6

I'm using EF 6 and Z.EntityFramework.Extensions.
The following code:
using (var context = contextFactory())
{
var modified = context.Receita.
Where(r => r.V_UID == receitaEletronica.VendaUid && r.numeroreceita == receitaEletronica.NumeroReceita).
Join(context.Tabela_Comparticipacao.
Where(t => entidades.Contains(t.ec_uid)).
Join(context.Tabela_Comparticipacao.Where(t => t.flag_elect == 1),
source => source.ec_uid,
dest => dest.ec_uid,
(source, dest) => new { Source = source, Dest = dest }),
r => r.TaCo_UID,
t => t.Source.TaCo_UID,
(r, t) => new { Receita = r, NovoTaCo = t.Dest.TaCo_UID }).
UpdateFromQuery(r => new Receita { TaCo_UID = r.NovoTaCo });
}
throws the following exception:
Message:
Test method winphar.services.receitas.ReceitasDAOTest.TestAtualizarReceitaElectronicaTaCoUidEntidadesCentralizadas threw exception:
System.Exception: Oops! Invalid update expression, the body is not a NewExpression. Please refer to the documentation to get examples about how to use this feature.
Stack Trace:
DbContextExtensions.[](IQueryable`1 , Expression`1 , Action`1 , Boolean )
DbContextExtensions.UpdateFromQuery[TEntity](IQueryable`1 query, Expression`1 updateExpression, Action`1 bulkOperationFactory)
DbContextExtensions.UpdateFromQuery[TEntity](IQueryable`1 query, Expression`1 updateExpression)
ReceitasDAO.AtualizarReceitaElectronicaTaCoUidEntidadesCentralizadas(ReceitaEletronica receitaEletronica, List`1 entidades) line 114
ReceitasDAOTest.TestAtualizarReceitaElectronicaTaCoUidEntidadesCentralizadas() line 267
What am I doing wrong?

I have received such error when context had different object then the one I was passing to UpdateFromQuery.
For example for context DbSet<A> I accidentally put new B()
context.A.
Where(x => x.Id == id).
UpdateFromQuery(x => new B
{
Example = exampleId
});
Hope it helps!

Related

Google.Apis.YouTube.v3 compiling channel statistics fail "The uri string is too long"

I'm trying to compile channel statistics for a list of channels and for the first page it works, but when I invoke the next page using the token it gives me an error that the URI string is too long.
I'm using .NET core 2.2 and Google.Apis.YouTube.v2 V1.39.0.1572. And the code I use is really simple:
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = Startup.Configuration["YTConfigurations:ApiKey"],
ApplicationName = this.GetType().ToString()
});
ChannelsResource.ListRequest channelsListRequest = youtubeService.Channels.List("snippet,statistics,brandingSettings,topicDetails");
channelsListRequest.Id = string.Join(",", channelEntities.Select(v => v.YTChannelId));
channelsListRequest.MaxResults = 50;
do
{
pageCounter++;
channelListResponse = channelsListRequest.Execute();//here is the error after page 1
foreach (var listResult in channelListResponse.Items)
{
channelEntity = channelEntities.FirstOrDefault(v => v.YTChannelId == listResult.Id);
channelEntity = Mapper.Map(listResult, channelEntity);
_repository.UpdateChannel(channelEntity);
}
if (channelListResponse.NextPageToken != null)
{
channelsListRequest.PageToken = channelListResponse.NextPageToken;
}
} while (channelListResponse.Items.Count == 50 && channelListResponse.NextPageToken != null);
When I execute this is what I get:
System.UriFormatException: Invalid URI: The Uri string is too long.
at System.UriHelper.EscapeString(String input, Int32 start, Int32 end, Char[] dest, Int32& destPos, Boolean isUriString, Char force1, Char force2, Char rsvd)
at System.Uri.EscapeDataString(String stringToEscape)
at Google.Apis.Requests.RequestBuilder.<>c.<BuildUri>b__25_0(KeyValuePair`2 x) in C:\Apiary\2019-05-01.11-08-18\Src\Support\Google.Apis.Core\Requests\RequestBuilder.cs:line 108
at System.Linq.Enumerable.SelectListIterator`2.ToArray()
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Google.Apis.Requests.RequestBuilder.BuildUri() in C:\Apiary\2019-05-01.11-08-18\Src\Support\Google.Apis.Core\Requests\RequestBuilder.cs:line 107
at Google.Apis.Requests.RequestBuilder.CreateRequest() in C:\Apiary\2019-05-01.11-08-18\Src\Support\Google.Apis.Core\Requests\RequestBuilder.cs:line 332
at Google.Apis.Requests.ClientServiceRequest`1.CreateRequest(Nullable`1 overrideGZipEnabled) in C:\Apiary\2019-05-01.11-08-18\Src\Support\Google.Apis\Requests\ClientServiceRequest.cs:line 257
at Google.Apis.Requests.ClientServiceRequest`1.ExecuteUnparsedAsync(CancellationToken cancellationToken) in C:\Apiary\2019-05-01.11-08-18\Src\Support\Google.Apis\Requests\ClientServiceRequest.cs:line 229
at Google.Apis.Requests.ClientServiceRequest`1.Execute() in C:\Apiary\2019-05-01.11-08-18\Src\Support\Google.Apis\Requests\ClientServiceRequest.cs:line 167
at ChannelHarvester.Controllers.ChannelHarvester.extractStats(ICollection`1 channelEntities) in C:\Guayaba Projects\YT_ChannelHarvester\ChannelHarvester\Controllers\ChannelHarvester.cs:line 106
Am I doing something wrong? Please let me know if there is something I can fix on my end.
Thanks!
Well, I'm really sorry to have bothered you guys. I found what it was, in the following code I thought I was joining only 50 IDs, but apparently in some occasions I was sending a LOT more.
channelsListRequest.Id = string.Join(",", channelEntities.Select(v => v.YTChannelId));
So I guess we can close this

Chaining Futures Do Not Execute In Order

I'm currently reading variables from a Bluetooth device. This obviously takes an undetermined amount of time, so I am using futures (This method is readCharacteristic in my code down below).
More than one read operation cannot take place at a time - if a second read operation is started while a first operation is still in progress, Flutter will throw an error.
My understanding was that chaining futures together using .then() would only allow the next statement to execute when the previous call had finished. This idea seems to be true until I try to read a third value - that is when the error is thrown, because of the overlapping read events.
Here is my code:
readCharacteristic(scanDurationCharacteristic)
.then((list) => sensorScanDuration = list[0].toDouble())
.then((_) {
readCharacteristic(scanPeriodCharacteristic)
.then((list) => sensorScanPeriod = list[0].toDouble());
}).then((_) {
readCharacteristic(aggregateCharacteristic)
.then((list) => sensorAggregateCount = list[0].toDouble());
}).then((_) {
readCharacteristic(appEUICharacteristic)
.then((list) => appEUI = decimalToHexString(list));
}).then((_) {
readCharacteristic(devEUICharacteristic)
.then((list) => devEUI = decimalToHexString(list));
}).then((_) {
readCharacteristic(appKeyCharacteristic)
.then((list) => appKey = decimalToHexString(list));
});
What is a better way to ensure that these read events will not overlap?
Although R.C Howell answer is correct, prefer using async/await keywords instead. This is much more readable and you're less likely to make an error
Future<void> scanBluetooth() async {
sensorScanDuration = (await readCharacteristic(scanDurationCharacteristic))[0].toDouble();
sensorScanPeriod = (await readCharacteristic(scanPeriodCharacteristic))[0].toDouble();
sensorAggregateCount = (await readCharacteristic(aggregateCharacteristic))[0].toDouble();
appEUI = await readCharacteristic(appEUICharacteristic).then(decimalToHexString);
devEUI = await readCharacteristic(devEUICharacteristic).then(decimalToHexString);
appKey = await readCharacteristic(appKeyCharacteristic).then(decimalToHexString);
}
If you would like to chain Futures, you must return the previous Future from within the then method of the previous Future.
The documentation says to chain like so,
expensiveA()
.then((aValue) => expensiveB())
.then((bValue) => expensiveC())
.then((cValue) => doSomethingWith(cValue));
Which is the same as,
expensiveA()
.then((aValue) {
return expensiveB();
}).then((bValue) {
return expensiveC();
}).then((cValue) => doSomethingWith(cValue));
As this applies to your case,
readCharacteristic(scanDurationCharacteristic)
.then((list) {
sensorScanDuration = list[0].toDouble();
return readCharacteristic(scanPeriodCharacteristic);
}).then((list) {
sensorScanPeriod = list[0].toDouble());
return readCharacteristic(aggregateCharacteristic);
}).then((list) {
sensorAggregateCount = list[0].toDouble());
return readCharacteristic(appEUICharacteristic);
}).then((list) {
appEUI = decimalToHexString(list));
return readCharacteristic(devEUICharacteristic);
}).then((list) {
devEUI = decimalToHexString(list));
return readCharacteristic(appKeyCharacteristic);
}).then((list) => appKey = decimalToHexString(list));

Check if some value already exist in database ASP.NET MVC?

How can I check if some value already exist in database I am doing MVC with Entity Framework and I want to check if element with composite key already exist in database application does someone has any suggestion i GOT the Json object but my done() method doesn't work?
I tried with JsonResult method from my controller
public JsonResult Check(int? id1, int? id2)
{
IQueryable<InspekcijskaKontrola> listaKontrola = db.InspekcijskeKontrole.Include(i => i.InspekcijskaTijela).Include(i => i.Proizvod).Select(i => i);
InspekcijskaKontrola inKontrola = listaKontrola.Where(i => i.InspekcijskoTijeloId == id1).Where(i => i.ProizvodId == id2).Select(i => i).Single();
if (inKontrola!=null)
{
return Json(inKontrola, JsonRequestBehavior.AllowGet);
}
return Json(new InspekcijskaKontrola { InspekcijskoTijeloId = -1, ProizvodId = -1 }, JsonRequestBehavior.AllowGet);
}
And I tried to rised modal dialog from my view with script
function prikazi() {
var zahtjev = $.getJSON("/InspekcijskeKontrole/Check?id1=" + $("#kombo3").val() + "&id2=" + $("#kombo4").val());
zahtjev.done(function (kontrola) {
if (kontrola.InspekcijskoTijeloId != -1 && kontrola.ProizvodId != -1) {
$("#p1").text("Inspekcijska kontrola za " + kontrola.ProizvodId + " je vec izvrsena");
$("#modalni1").modal({ backdrop: "static" });
}
});
}
Providing a bit of code would really help. However, right off the bat I could suggest you use something like this to search for a key(or more) from an object:
if(dbContext.Items.Any(anyObjectName=>anyObjectName.firstKey == ValueYouLookFor
&& anyObjectName.secondkey == AnotherValue))
{
//logic to apply if object exists
}

Why am I getting Zxing.Mobile.MobileBarcodeScanner( ) constructor error?

I am using Zxing.Mobile to scan a barcode in my monodroid app. I am using Xamarin. According to their documentation following line of code should work:
var scanner = new ZXing.Mobile.MobileBarcodeScanner();
scanner.Scan().ContinueWith(t => {
if (t.Result != null)
Console.WriteLine("Scanned Barcode: " + t.Result.Text);
});
But i am getting following error:
The type 'Zxing.Mobile.MobileBarcodeScanner()' does not contain a constructor that takes '0' arguments
Any idea why am i getting this error and how can i get rid of it? Thanks in advance.
You need to provide the Context, as mentioned above, he just didn't put the context into the constructor. Heh. Hence causing confusion.
var scanner = new ZXing.Mobile.MobileBarcodeScanner(this.Context);
scanner.Scan().ContinueWith(t => {
if (t.Result != null)
Console.WriteLine("Scanned Barcode: " + t.Result.Text);
});`
This works for me
async void HandleBarcodeButtonClick(object sender, EventArgs e)
{
var scanner = new ZXing.Mobile.MobileBarcodeScanner(this);
string barcode = string.Empty;
await scanner.Scan().ContinueWith(t =>
{
if (t.Result != null)
barcode = t.Result.Text;
});
}
The constructor needs more than 0 arguments. From here:
//NOTE: On Android you MUST pass a Context into the Constructor!
var scanner = new ZXing.Mobile.MobileBarcodeScanner();
scanner.Scan().ContinueWith(t => {
if (t.Result != null)
Console.WriteLine("Scanned Barcode: " + t.Result.Text);
});

Async Futures running in sequence to completion

I encountered the following example (Example 1 below) of Futures which caused me to wonder if I could alter the way that I was handling Futures and remove all of the nested function calls that preserve order of processing, which however result in indentation which I find a bit messy.
The altered version of my program did not work however. It did not preserve the order of processing and did not “wait” for function to complete. For example, before returning from the first call (fGetUserInput), another subsequent function was called.
Why is it that in Example 1, all of the “1st level” “new Future”s processed sequentially, however in Example 2, my altered code, the order of processing is not preserved. While the call to fGetUserInput is being processed, one of the Futures that follows it is processed?
Is it perhaps that “Example 1” only “works” because all of the statements are synchronous?
I came across a reference to “runAsync”. Can that be used to achieve what I want? (process in sequence without all of the indentation).
// Example 1. Code that I encountered for Futures //
import 'dart:async';
main() {
new Future(() => print('1'))
.then((_) => print('a'))
.then((_) => print('b'));
new Future(() => print('2'))
.then((_) => print('c'))
.then((_) => print('d'));
new Future(() => print('3'))
.then((_) =>
new Future(() => print('e'))
.then((_) => print('f'))
);
new Future(() => print('4'))
.then((_) =>
new Future(() => print('g'))
.then((_) => print('d'))
);
}
The above results in the following console output order :-
1 a b 2 c d 3 4 e f g d
Which I thought made sense.
Therefore, I modified my code to test it as follows :-
// Example 2. Altered version of my code which //
// does not preserve the order of processing, //
// which is necessary for program to function. //
new async.Future(() => fGetUserInput())
.then((lInput) {
iMaxIters = int.parse(lInput[4]);
tClearTable = (lInput[5] == "y");
iDivisor = fInitialize(iMaxIters);
tgPrint = false; // printing off
sUri =
"postgres://${lInput[1]}:${lInput[2]}#localhost:5432/${lInput[3]}";
sStartTime = lInput[7];
})
.catchError((oError) => fFatal("Get User Input", oError));
new async.Future(() => fConnectToDb(sUri, sStartTime))
.then((bool tConnected) {
if (ogDb == null)
fFatal("Unable to connect to database", "");
print ("Processing database ......");
})
.catchError((oError) => fFatal("Connect to Db", oError));
new async.Future(() => fClearTable(tClearTable))
.then((sResult) => print (sResult+"\n"))
.catchError((oError) => fFatal("Clear Table", oError));
new async.Future(() => fProcessInserts(iMaxIters, iDivisor))
.then((sResult) => print (""))
.catchError((oError) => fFatal("Process Inserts", oError));
new async.Future(() => fSetupRandKeys())
.then((sResult) => print (""))
.catchError((oError) => fFatal("Setup Random Keys", oError));
new async.Future(() => fProcessUpdates(iMaxIters, iDivisor))
.then((sResult) {
String sTotValue = fFormatAmount(igGrandTotAmt, true, 2);
fPrint ("Grand Total added to database = \$${sTotValue}");
ogDb.close();
exit(0);
})
.catchError((oError) => fFatal("Process Updates", oError));
}
void fFatal (String sMessage, Error oError) {
print("\n\nFatal Error. $sMessage\n${oError}");
exit(1);
}
async.Future<String> fProcessInserts(int iMaxIters, int iDiv) {
async.Completer oCompleter = new async.Completer<String>();
int iTot = 0;
Function fLoop;
print ("\nProcessing Inserts ......");
fResetAndStartWatch();
The following is my code prior to the above changes, and the following Example 3 appears to work OK. I don't like the extent of indentation, and in situations with more function calls, that would increase the extent of indentation. I was hoping for a more elegant way to do it.
// Example 3: The original version of my code //
// which does preserve the order of processing //
void main() {
print("");
String sCheckPoint = "Get User Input";
fGetUserInput()
.then((lInput) {
int iMaxIters = int.parse(lInput[4]);
bool tClearTable = (lInput[5] == "y");
int iDiv = fInitialize(iMaxIters);
tgPrint = false; // printing off
String sUri =
"postgres://${lInput[1]}:${lInput[2]}#localhost:5432/${lInput[3]}";
sCheckPoint = "Connect to Database";
fConnectToDb(sUri, lInput[7]).then((bool tConnected) {
if (ogDb == null)
fFatal(sCheckPoint, "Unable to conenct to Db");
print ("Processing database ......");
sCheckPoint = "Clear Table";
fClearTable(tClearTable).then((sResult) {
print (sResult+"\n");
sCheckPoint = "Process Inserts";
fProcessInserts(iMaxIters, iDiv).then((sResult) {
print;
sCheckPoint = "Set-up Random Keys";
fSetupRandKeys().then((sResult) {
print;
sCheckPoint = "Process Updates";
fProcessUpdates(iMaxIters, iDiv).then((sResult) {
String sTotValue = fFormatAmount(igGrandTotAmt, true, 2);
fPrint ("Grand Total added to database = \$${sTotValue}");
ogDb.close();
exit(0);
});
});
});
});
});
})
.catchError((oError) => fFatal(sCheckPoint, oError));
}
void fFatal (String sMessage, Error oError) {
print("\n\nFatal Error. $sMessage\n${oError}");
exit(1);
}
async.Future<String> fProcessInserts(int iMaxIters, int iDiv) {
async.Completer oCompleter = new async.Completer<String>();
int iTot = 0;
Function fLoop;
print ("Processing Inserts ......");
fResetAndStartWatch();
Remember that you can chain futures, which will reduce your indentation by quite a bit.
The downside is that you don't get nested scopes, which can be useful if you have more than one value to propagate between async blocks, but that can be worked around in a few ways.
Here's you example 3 with chaining:
// Example 3 with chaining
void main() {
String checkPoint = "Get User Input";
getUserInput().then((input) {
int maxIters = int.parse(input[4]);
bool clearTable = (input[5] == "y");
int div = initialize(maxIters);
shouldPrint = false; // printing off
String uri =
"postgres://${input[1]}:${input[2]}#localhost:5432/${input[3]}";
checkPoint = "Connect to Database";
return connectToDb(uri, input[7]).then((bool connected) {
if (db == null)
fatal(checkPoint, "Unable to conenct to Db");
print ("Processing database ......");
checkPoint = "Clear Table";
return clearTable(shouldClearTable);
}).then((result) {
print (result+"\n");
checkPoint = "Process Inserts";
return processInserts(maxIters, div);
}).then((result) {
print('');
checkPoint = "Set-up Random Keys";
return setupRandKeys();
}).then((result) {
print('');
checkPoint = "Process Updates";
return processUpdates(maxIters, div);
}).then((result) {
String totValue = formatAmount(grandTotAmt, true, 2);
print("Grand Total added to database = \$${totValue}");
return db.close();
// exit(0); pretty much never call exit()
});
}).catchError((error) => fatal(checkPoint, error));
}
Edit: Oops, looking more closely I got bit by the scoping problem... I added a level of nesting just to capture the needed vars in a scope accessible by the following blocks. I'm also removing the hungarian-ish notation, because... don't do that in Dart :)

Resources