db4o creating event not fire on db4o 8 - c#-3.0

i am using db4o 8 with c# 3.5, The TA and TP is enabled on all of my domain model classes.
the problem is i have my own ID Generator attached to creating event with following code:
IEventRegistry eventRegistry = EventRegistryFactory.ForObjectContainer(Container);
eventRegistry.Creating += new EventHandler(eventRegistry_Creating);
i have a USER class containing a list of ORDER.
problem is if i update the USER class, creating event does not fire for new added ORDER objects in USER.ORDERS.
before version 8 i used v7.4 and it worked fine, but today i upgraded it to v8 to gain some performance benefits but this problem occurred.
would you please help me to fix this problem ?

I tried to reproduce the issue and it worked for me fine. Are you sure that the added order is actually stored? What kind of collection are you using? The db4o activatable collections or the regular CLR collections? And which version did you use?
Here my little test-case which worked:
var eventRegistry = EventRegistryFactory.ForObjectContainer(container);
var expectFireCreated = false;
eventRegistry.Created += (sender, args) =>
{
expectFireCreated = true;
};
var costumer = (from Constumer c in container
select c).First();
costumer.Orders.Add(new Order("55"));
container.Commit();
Assert.IsTrue(expectFireCreated);

Related

Getting error - Npgsql.NpgsqlOperationInProgressException: 'A command is already in progress: SELECT c."Id"

We are migrating our netcore project from 2.2 to 6. And we are getting error message Npgsql.NpgsqlOperationInProgressException: 'A command is already in progress: SELECT ..
We have upgraded postgre and entity framework nudget packages as well to latest and stable one.
Earlier, same code was working perfectly fine. I have gone through several online links for the same error and per them it is happening as Postgre doesn't support the MARS. However, earlier it was working fine then how it's possible? Is Postgre doesn't support MARS after 2.2 version?
We are calling select statment inside the foreach loop. Please find the code snippet below:
var obj = service.GetData().Select(o => new Object
{
Id = o.Id,
Title = o.Title,
AdminId = service.GetAdminId(o.Id)
}).ToList();
public int GetAdminId(int id)
{
var obj = unitOfWork.Repository<entity>().GetSingle(x => x.IsActive && x.cId == id);
return obj.adminId;
}
I am stuck with this upgradation process so please provide you input
Please provide some light on it if Postgre doesn't support MARS then how we can resolve this issue

How to configure, map and use Entity Framework 6 Power Tools Community Edition

We have a project configured with Entity Framework v6.1.3 with a database-first approach and TargetFramework="net45". We are using Devexpress OData web API service.
We have been updating entities for years and it is working fine however when it comes to large volume of data our WPF application gets slow at first time.
We believe when we execute query for the first time it gets slow and then we close and reopen same form it becomes faster so we might believe using Entity Framework 6 Power Tools Community Edition could solve our problem regarding of slowness.
https://learn.microsoft.com/en-us/ef/ef6/fundamentals/performance/pre-generated-views
We used this Microsoft link to get help however we didn't get much help on this
We have come so far to generate (Pre-generated mapping views and DataModel.Views.cs) files successfully as per describe in the link however the further process we did not get much help and getting no idea how we can properly use it
var objectContext = ((IObjectContextAdapter) dbContext).ObjectContext;
var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace
.GetItemCollection(DataSpace.CSSpace);
if anyone could help on related to this topic it would be much help
public class objectMapping
{
MyDB_Entities context { get; set; }
public objectMapping()
{
context = new ERPDB_Entities();
GenerateViewCache();
}
private void GenerateViewCache()
{
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace.GetItemCollection(DataSpace.CSSpace);
var mappingHashValue = mappingCollection.ComputeMappingHashValue();
var edmSchemaError = new List<EdmSchemaError>();
var views = mappingCollection.GenerateViews(edmSchemaError);
}
}
I created above class and call in Application_Start to Generate ViewCache
protected void Application_Start()
{
new objectMapping();
}
does any one knows that i implemented this in right way?

Entity Framework new object vs DbSet.Create

We are migrating a web application from EF 4.0 to EF 6. The entities were earlier based on ObjectContext, but now we are looking at DBContext. The code heavily depends on lazy loading. Entities are added using following syntax:
var user = new EntityModel.User();
user.DepratmentId=25;
context.Users.Add(user);
context.SaveChanges();
var name = user.Department.Name;
the original code would easily assign department name into variable name. After Entity framework upgrade to EF6 with DBContext, user.Department is null. I understand that when we are using DBContext, Lazy Loading works only with Proxies. It would work fine if the code was changed to following:
var user = context.Users.Create();
user.DepratmentId=25;
context.Users.Add(user);
context.SaveChanges();
var name = user.Department.Name;
Problem at my hand is that we can not make this change in the whole code base. Given the large volume of code, this is practically impossible. Does someone have a solution to this?
Provided your entities are easily identifiable such as all being pulled from the namespace "EntityModel" then VS's Find & Replace can help with the transition. Ultimately you're going to have to eat the cost of that technical debt. Re-factoring isn't free, but the benefit from making improvements (beyond just upgrading a dependency version) should outweigh that cost.
Using Find & Replace:
Find: = new EntityModel.(?<class>.*)\(\)
Replace: = context.${class}s.Create()
This will find instances like:
var user = new EntityModel.User();
and replace it with var user = context.Users.Create();
a test with:
var user = new EntityModel.User();
var test = new EntityModel.Test();
var fudge = new EntityModel.Fudge();
resulted in:
var user = context.Users.Create();
var test = context.Tests.Create();
var fudge = context.Fudges.Create();
Now this will extract the class name and pluralize it with an 's' which likely won't match 100% of the entity DBSet names, but those are easily found and corrected. The expressions can be tuned to suit differences through the application and I would recommend performing the operation on a file by file, or at most project by project basis.
An caveat is to make sure you're running with source control so that any bad attempts at a replace can be rolled back safely.

Disable logging on FileConfigurationSourceChanged - LogEnabledFilter

I want Administrators to enable/disable logging at runtime by changing the enabled property of the LogEnabledFilter in the config.
There are several threads on SO that explain workarounds, but I want it this way.
I tried to change the Logging Enabled Filter like this:
private static void FileConfigurationSourceChanged(object sender, ConfigurationSourceChangedEventArgs e)
{
var fcs = sender as FileConfigurationSource;
System.Diagnostics.Debug.WriteLine("----------- FileConfigurationSourceChanged called --------");
LoggingSettings currentLogSettings = e.ConfigurationSource.GetSection("loggingConfiguration") as LoggingSettings;
var fdtl = currentLogSettings.TraceListeners.Where(tld => tld is FormattedDatabaseTraceListenerData).FirstOrDefault();
var currentLogFileFilter = currentLogSettings.LogFilters.Where(lfd => { return lfd.Name == "Logging Enabled Filter"; }).FirstOrDefault();
var filterNewValue = (bool)currentLogFileFilter.ElementInformation.Properties["enabled"].Value;
var runtimeFilter = Logger.Writer.GetFilter<LogEnabledFilter>("Logging Enabled Filter");
runtimeFilter.Enabled = filterNewValue;
var test = Logger.Writer.IsLoggingEnabled();
}
But test reveals always the initially loaded config value, it does not change.
I thought, that when changing the value in the config the changes will be propagated automatically to the runtime configuration. But this isn't the case!
Setting it programmatically as shown in the code above, doesn't work either.
It's time to rebuild Enterprise Library or shut it down.
You are right that the code you posted does not work. That code is using a config file (FileConfigurationSource) as the method to configure Enterprise Library.
Let's dig a bit deeper and see if programmatic configuration will work.
We will use the Fluent API since it is the preferred method for programmatic configuration:
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions
.DoNotRevertImpersonation()
.FilterEnableOrDisable("EnableOrDisable").Enable()
.LogToCategoryNamed("General")
.WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("FlatFile")
.ToFile(#"fluent.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
var defaultWriter = new LogWriterFactory(configSource).Create();
defaultWriter.Write("Test1", "General");
var filter = defaultWriter.GetFilter<LogEnabledFilter>();
filter.Enabled = false;
defaultWriter.Write("Test2", "General");
If you try this code the filter will not be updated -- so another failure.
Let's try to use the "old school" programmatic configuration by using the classes directly:
var flatFileTraceListener = new FlatFileTraceListener(
#"program.log",
"----------------------------------------",
"----------------------------------------"
);
LogEnabledFilter enabledFilter = new LogEnabledFilter("Logging Enabled Filter", true);
// Build Configuration
var config = new LoggingConfiguration();
config.AddLogSource("General", SourceLevels.All, true)
.AddTraceListener(flatFileTraceListener);
config.Filters.Add(enabledFilter);
LogWriter defaultWriter = new LogWriter(config);
defaultWriter.Write("Test1", "General");
var filter = defaultWriter.GetFilter<LogEnabledFilter>();
filter.Enabled = false;
defaultWriter.Write("Test2", "General");
Success! The second ("Test2") message was not logged.
So, what is going on here? If we instantiate the filter ourselves and add it to the configuration it works but when relying on the Enterprise Library configuration the filter value is not updated.
This leads to a hypothesis: when using Enterprise Library configuration new filter instances are being returned each time which is why changing the value has no effect on the internal instance being used by Enterprise Library.
If we dig into the Enterprise Library code we (eventually) hit on LoggingSettings class and the BuildLogWriter method. This is used to create the LogWriter. Here's where the filters are created:
var filters = this.LogFilters.Select(tfd => tfd.BuildFilter());
So this line is using the configured LogFilterData and calling the BuildFilter method to instantiate the applicable filter. In this case the BuildFilter method of the configuration class LogEnabledFilterData BuildFilter method returns an instance of the LogEnabledFilter:
return new LogEnabledFilter(this.Name, this.Enabled);
The issue with this code is that this.LogFilters.Select returns a lazy evaluated enumeration that creates LogFilters and this enumeration is passed into the LogWriter to be used for all filter manipulation. Every time the filters are referenced the enumeration is evaluated and a new Filter instance is created! This confirms the original hypothesis.
To make it explicit: every time LogWriter.Write() is called a new LogEnabledFilter is created based on the original configuration. When the filters are queried by calling GetFilter() a new LogEnabledFilter is created based on the original configuration. Any changes to the object returned by GetFilter() have no affect on the internal configuration since it's a new object instance and, anyway, internally Enterprise Library will create another new instance on the next Write() call anyway.
Firstly, this is just plain wrong but it is also inefficient to create new objects on every call to Write() which could be invoked many times..
An easy fix for this issue is to evaluate the LogFilters enumeration by calling ToList():
var filters = this.LogFilters.Select(tfd => tfd.BuildFilter()).ToList();
This evaluates the enumeration only once ensuring that only one filter instance is created. Then the GetFilter() and update filter value approach posted in the question will work.
Update:
Randy Levy provided a fix in his answer above.
Implement the fix and recompile the enterprise library.
Here is the answer from Randy Levy:
Yes, you can disable logging by setting the LogEnabledFiter. The main
way to do this would be to manually edit the configuration file --
this is the main intention of that functionality (developers guide
references administrators tweaking this setting). Other similar
approaches to setting the filter are to programmatically modify the
original file-based configuration (which is essentially a
reconfiguration of the block), or reconfigure the block
programmatically (e.g. using the fluent interface). None of the
programmatic approaches are what I would call simple – Randy Levy 39
mins ago
If you try to get the filter and disable it I don't think it has any
affect without a reconfiguration. So the following code still ends up
logging: var enabledFilter = logWriter.GetFilter();
enabledFilter.Enabled = false; logWriter.Write("TEST"); One non-EntLib
approach would just to manage the enable/disable yourself with a bool
property and a helper class. But I think the priority approach is a
pretty straight forward alternative.
Conclusion:
In your custom Logger class implement a IsLoggenabled property and change/check this one at runtime.
This won't work:
var runtimeFilter = Logger.Writer.GetFilter<LogEnabledFilter>("Logging Enabled Filter");
runtimeFilter.Enabled = false/true;

Phonegap and Nova Data Framework -

I am learning PhoneGap for an app project and need to use the database for certain aspects, I am trying out the Nova Data framework,
https://cordova.codeplex.com/wikipage?title=How%20to%20use%20nova.data
I am trying to use my code to put together a test entity, but I am getting a db error telling me there is a missing table. The documentation does not specify that the database should be created beforehand, but I am starting to think that may be the case. Has anyone out there used the Nova framework in a project? I just need a little guidance.
Here is my code I am using to kick off the DB Context:
var DataContext = function () {
nova.data.DbContext.call(this, "HealthDb", "1.0", "Health DB", 1000000);
this.Temperatures = new nova.data.Repository(this, Temperature, "Temperatures");
};
DataContext.prototype = new nova.data.DbContext();
DataContext.constructor = DataContext;
And my entity (Temperature) :
var Temperature = function () {
nova.data.Entity.call(this);
this.Value = 101;
};
Temperature.prototype = new nova.data.Entity();
Temperature.constructor = Temperature;
It is creating an empty database with the proper name, just no tables! I am grateful for any assistance!
Thanks for using our library. I have made the html5 sqlite as a standalone library. Please get it from github.
A live demo link is also available there. And the documentation is more complete. The lib itself has also been updated and a few bugs fixed.
Thanks,
Leo
Turns out I was trying to start up the dbcontext before I defined my entity classes....
Changed the order of my js files and it works.