MongoDB Unknown discriminator value - mongodb

I've added the code in the answer to this question: Unknown discriminator value 'MyEvent', but it didn't help.
An error occurred while deserializing the Body property of class EventStore.EventMessage: Unknown discriminator value : "Insert event name".
Error only occurs when you try to rehydrate a saved object after program restart.
Running latest MyGet Build
Sample Repository:https://github.com/tonyeung/EventStore-MongoDB
To replicate the issue:
run the program
press c to create a new record
press q to quit
run the program again
but press r to rehydrate
error triggers
If you run the program, press c, press enter to continue, and press r to rehydrate without quitting, the object is rehydrated without a problem. WAT?
using (var eventStore = WireupEventStore())
{
var snapshot = eventStore.Advanced.GetSnapshot(ID, int.MaxValue);
if (snapshot == null)
{
// ERRORS HERE
using (var stream = eventStore.OpenStream(ID, 0, int.MaxValue))
{
var events = from s in stream.CommittedEvents
select s.Body as IEvent;
obj.LoadsFromHistory(events);
}
}
}
github issue: https://github.com/NEventStore/NEventStore/issues/203

I figured it out, since I was using an interface as a marker for my events, I had to change the query from the SO question from
var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
to
var type = typeof(IEvent);
var types = Assembly.GetAssembly(typeof(IEvent))
.GetTypes()
.Where(t => type.IsAssignableFrom(t))
.Where(t => t.IsClass);

Related

How do you update the CanExecute value after the ReactiveCommand has been declared

I am using ReactiveUI with AvaloniaUI and have a ViewModel with several ReactiveCommands namely Scan, Load, and Run.
Scan is invoked when an Observable<string> is updated (when I receive a barcode from a scanner).
Load is triggered from within the Scan command.
Run is triggered from a button on the UI.
Simplified code below:
var canRun = Events.ToObservableChangeSet().AutoRefresh().ToCollection().Select(x => x.Any());
Run = ReactiveCommand.CreateFromTask<bool>(EventSuite.RunAsync, canRun);
var canLoad = Run.IsExecuting.Select(x => x == false);
var Load = ReactiveCommand.CreateFromTask<string, Unit>(async (barcode) =>
{
//await - go off and load Events.
}, canLoad);
var canReceiveScan = Load.IsExecuting.Select(x => x == false)
.Merge(Run.IsExecuting.Select(x => x == false));
var Scan = ReactiveCommand.CreateFromTask<string, Unit>(async (barcode) =>
{
//do some validation stuff
await Load.Execute(barcode)
}, canReceiveScan);
Barcode
.SubscribeOn(RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.MainThreadScheduler)
.InvokeCommand(Scan);
Each command can only be executed if no other command is running (including itself). But I can't reference the commands' IsExecuting property before is it declared. So I have been trying to merge the "CanExecute" observable variables like so:
canRun = canRun
.Merge(Run.IsExecuting.Select(x => x == false))
.Merge(Load.IsExecuting.Select(x => x == false))
.Merge(Scan.IsExecuting.Select(x => x == false))
.ObserveOn(RxApp.MainThreadScheduler);
// same for canLoad and canScan
The issue I'm having is that the ReactiveCommand will continue to execute when another command is executing.
Is there a better/correct way to implement this?
But I can't reference the commands' IsExecuting property before is it declared.
One option is to use a Subject<T>, pass it as the canExecute: parameter to the command, and later emit new values using OnNext on the Subject<T>.
Another option is to use WhenAnyObservable:
this.WhenAnyObservable(x => x.Run.IsExecuting)
// Here we get IObservable<bool>,
// representing the current execution
// state of the command.
.Select(executing => !executing)
Then, you can apply the Merge operator to the observables generated by WhenAnyObservable. To skip initial null values, if any, use either the Where operator or .Skip(1).
To give an example of the Subject<T> option described in the answer by Artyom, here is something inspired by Kent Boogaart's book p. 82:
var canRun = new BehaviorSubject<bool>(true);
Run = ReactiveCommand.Create...(..., canExecute: canRun);
Load = ReactiveCommand.Create...(..., canExecute: canRun);
Scan = ReactiveCommand.Create...(..., canExecute: canRun);
Observable.Merge(Run.IsExecuting, Load.IsExecuting, Scan.IsExecuting)
.Select(executing => !executing).Subscribe(canRun);

Error "The given key was not present in the dictionary" When Creating New Custom Entity on Update Event

On CRM 2013 on-premise, I'm trying to write a plugin that triggers when an update is made to a field on Quote. The plugin then creates a new custom entity "new_contract".
My plugin is successfully triggered when the update to that field is made. However I keep getting an error message "The given key was not present in the dictionary" when trying to create the new custom entity.
I'm using a "PostImage" in this code. I confirm that it's registered using the same name in Plugin Registration.
Here is the code
var targetEntity = context.GetParameterCollection<Entity>
(context.InputParameters, "Target");
if (targetEntity == null)
{throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Target Entity cannot be null")}
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
{throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Post Image is required");}
var quote = context.GenerateCompositeEntity(targetEntity, postImage);
//throw new InvalidPluginExecutionException(OperationStatus.Failed, "Update is captured");
//Guid QuoteId = (Guid)quote.Attributes["quoteid"];
var serviceFactory = (IOrganizationServiceFactory)serviceProvider
.GetService(typeof(IOrganizationServiceFactory));
var service = serviceFactory.CreateOrganizationService(context.UserId);
var contractEntity = new Entity();
contractEntity = new Entity("new_contract");
if (quote.Attributes.Contains("portfolio"))
{
var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
contractEntity[Schema.new_contract.PortfolioName] =
new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
if (quote.Attributes.Contains(Schema.Quote.QuoteName))
{
var quoteName = (string)quote.Attributes["name"];
contractEntity[Schema.new_contract.contractName] = quoteName;
}
var contractId = service.Create(contractEntity);
I think context does not contain "PostImage" attribute.You should check context to see whether it contains the attribute before getting the data.
Looking at this line in your post above:
var service = serviceFactory.CreateOrganizationService(context.UserId);
I am deducing that the type of your context variable is LocalPluginContext (since this contains the UserId value) which does not expose the images (as another answer states).
To access the images, you need to get to the Plugin Execution Context:
IPluginExecutionContext pluginContext = context.PluginExecutionContext;
Entity postImage = null;
if (pluginContext.PostEntityImages != null && pluginContext.PostEntityImages.Contains("PostImage))
{
postImage = pluginContext.PostEntityImages["PostImage"];
}
In the below code segment, you are checking for the attribute "portfolio" and using "new_portfolio". Can you correct that and let us know whether that worked.
if (quote.Attributes.Contains("portfolio"))
{
var quotePortfolio = (EntityReference)quote.Attributes["new_portfolio];
contractEntity[Schema.new_contract.PortfolioName] = new EntityReference(quotePortfolio.LogicalName, quotePortfolio.Id);
}
First, you don't say what line is throwing the exception. Put in the VS debugger and find the line that is throwing the exception.
I did see that you are trying to read from a dictionary here without first checking if the dictionary contains the key, that can be the source of this exception.
var postImage = context.PostEntityImages["PostImage"];
if (postImage == null)
throw new InvalidPluginExecutionException(OperationStatus.Failed,
"Post Image is required");
Try this:
if(!context.PostEntityImages.Contains("PostImage") ||
context.PostEntityImages["PostImage"] == null)
InvalidPluginExecutionException(OperationStatus.Failed, "Post Image is required");
var postImage = context.PostEntityImages["PostImage"];
Although, I don't think that a PostEntityImage Value will ever be null, if it passes the Contains test you don't really need the null check.

How to obtain a subset of records within a context using EntityFramework?

A newbie question. I am using EntityFramework 4.0. The backend database has a function that will return a subset of records based on time.
Example of working code is:
var query = from rx in context.GetRxByDate(tencounter,groupid)
select rx;
var result = context.CreateDetachedCopy(query.ToList());
return result;
I need to verify that a record does not exist in the database before inserting a new record. Before performing the "Any" filter, I would like to populate the context.Rxes with a subset of the larger backend database using the above "GetRxByDate()" function.
I do not know how to populate "Rxes" before performing any further filtering since Rxes is defined as
IQueryable<Rx> Rxes
and does not allow "Rxes =.. ". Here is what I have so far:
using (var context = new EnityFramework())
{
if (!context.Rxes.Any(c => c.Cform == rx.Cform ))
{
// Insert new record
Rx r = new Rx();
r.Trx = realtime;
context.Add(r);
context.SaveChanges();
}
}
I am fully prepared to kick myself since I am sure the answer is simple.
All help is appreciated. Thanks.
Edit:
If I do it this way, "Any" seems to return the opposite results of what is expected:
var g = context.GetRxByDate(tencounter, groupid).ToList();
if( g.Any(c => c.Cform == rx.Cform ) {....}

Entity Framework check against a local list

I have a local list of values that I need to have entity framework check against the database and return them.
If the list was already in the database, the following would work:
var list = /* some ef query */;
var myList = context.Logs.Where(l => list.Any(li => l.LogNumber == li.LogNumber));
But if the list is local, it would throw an error:
var list = new List<Log>();
var myList = context.Logs.Where(l => list.Any(li => l.LogNumber == li.LogNumber));
Exception: Unable to process the type 'Data.Log[]', because it has no known mapping to the value layer.
So how can I match a local list against a database list using EF?
I got a different error than you with the code sample, but I believe it's the same idea. EF doesn't know how to translate List<Log> into a SQL store expression. It works when you're still in a query because it hasn't been serialized yet.
I realize this is less than ideal, but I was able to make this query work by extracting the scalar values of LogNumber and then using that in the query.
var list = new List<Log>();
list.Add(new Log()
{
LogNumber = 1
});
var numbers = list.Select(l => l.LogNumber);
var myList = m.Logs.Where(l => numbers.Contains(l.LogNumber));

What is the difference between using and not using using statement with DbContext [code first]?

I'm wondering what the difference between...
using (var db = new PteDotNetContext())
{
var blog = new Blog() { BlogType = 1, Title = "Blog 1", Description = TestInfo.UniqueRecordIdentifier, DateAdded = DateTime.Now, User = TestInfo.UniqueRecordIdentifier };
db.Blogs.Add(blog);
db.SaveChanges();
}
PteDotNetContext context2 = new PteDotNetContext();
var blog2 = new Blog() { BlogType = 1, Title = "Blog 2", Description = TestInfo.UniqueRecordIdentifier, DateAdded = DateTime.Now, User = TestInfo.UniqueRecordIdentifier };
context2.Blogs.Add(blog2);
context2.SaveChanges();
is. I understand that using a using statement basically calls the destructor on the object. I just wonder...
a) Does the using statement open and then close a Sql connection on the DbContext?
b) If so what happens with the second statement because i never actually opened it and it still works. So when do I close the statement?
a) Does the using statement open and then close a Sql connection on
the DbContext?
The variable declared inside using statement is Disposed when using block is ended. On DbContext the disposal method closes the connection, so as soon as that code block is ended the connection is closed.
b) If so what happens with the second statement because i never
actually opened it and it still works. So when do I close the
statement?
Garbage collector clears the context object when it is no longer needed and the connection is being closed then.
You should read about using statement and IDisposable.