db4o How to rename class via configuration - c#

I am using db4o in two seperate projects that share the same classes but not the same .dll . I am fixing this so that they share the same .dll but I need to rename the classes. According to the documentation you set up configuration and open the db with the renames and it updates everything. I have tried this but when I try to open the DB the project just hangs. Am I missing something here
config.Common.ObjectClass("DllName.Old, DllName")
.Rename("NewDll.New, NewDll");
var db = Db4oEmbedded.OpenFile(config, DBFile);

That looks correct to me and should work. It really should work when the class-names and assembly names are correct. The class is not a generic class, right?
You don't get any exception, right? Is db4o just hanging or actually doing some work?
Edit: I could reproduce a stack-overflow exception with renaming a class. Maybe you are running into a stack overflow exception as well, but you cancel it before it actually happens?
Anyway, I created a bug-entry in the db4o-bugtracker.

I was successful with the following answer:
https://stackoverflow.com/a/1138178/541420
Very buggy otherwise though :(

Related

Why can't I use file extensions in Entity Framework Core Sqlite files?

When I try to use Entity Framework Core with Sqlite and a file extension of .db or .sqlite, I get an error
SqliteException: SQLite Error 14: 'unable to open database file'
If I remove the file extension, then it works fine.
I'm not very familiar with Entity Framework Core, and have been using things like npoco in the past. I'm working on a DataStorage and DataAggregator and I'm experiencing issues that require implementation of some hackery. I don't like it and it makes me feel dirty.
If I remove the .db from the connection string, then it works just fine, but if I leave any file extension on (I've only tried .db and .sqlite), I get that error.
Steps to recreate:
Clone https://github.com/EdLichtman/DataStorageService
dotnet run this solution (or play with the Unit Tests) and go to AggregateResults ControllerAction in your browser. It will try to find all files that end in .db and all that end in _db_metadata.json and will find none and will return "0" to the browser page.
Now go to the DataStorageService\DataStorageService\TransmittedFiles repository and clear it out. Go to
Endpoints\DataStorage\AggregateData\AggregateDataContext.cs. Comment out the lines
if (OperatingSystemHelpers.IsOSWindows)...
up until
.Remove(connectionStringFileLocation.Length - 3);
Try to do exactly what you did before and you will see that 1) the AggregateData.db file is still created in TransmittedFiles, and 2) you should see the SqliteError 14.
If you clear the TransmittedFiles folder out again and try it with the OperatingSystemHelpers Clause back in, you'll see that it works. Meaning it isn't a matter of the file not existing.
The issue results from the previous connection still having access to the file.
As mentioned in the thread below Sqlite's C# implementation has a quirk where after a .Close() the connection is not truly cleaned up until a garbage collect runs
System.Data.SQLite Close() not releasing database file
To fix it you could add IDisposable to your IAggregateDataRepository and implement something similar like the following dispose method:
public void Dispose()
{
_database.Dispose();
GC.Collect();
GC.WaitForPendingFinalizers();
}
You will need to call the disposers in your tests, this could be done by adding the following to the top of your TearDown method:
if (_aggregateDataRepository != null)
{
_aggregateDataRepository.Dispose();
}
As an extra bit of advice if you add this line at the end of the app context constructor it will ensure you are always in "Write Ahead Log" mode which is more happy with multiple connections. This isnt needed to fix the issue but as you look to be creating a restful web api interface on sqlite it will assist with concurrent calls.
Database.ExecuteSqlCommand("PRAGMA journal_mode=WAL;");
Further details
https://www.sqlite.org/wal.html

Keep a specific "using" statement when cleaning up code

I am a huge fan of keyboard shortcuts. I am especially fond of Remove and Sort Usings in Visual Studio. Until now, I had no reason to question the use of such a command. I recently discovered that a using statement existed in several files but was not actually used at all in the files. I had no problems letting the command wipe it from my view until I tried to update service reference and discovered that some properties could not be serialized. using System.Runtime.Serialization; would allow the classes in question to be reflected with whatever magic was required to update the service reference. Having added this line back into several classes, teaching several people I work with shortcuts to help keep their code clean, and general forgetfulness, I can see this line being removed at some point in the future and someone new wondering why things won't serialize anymore.
Is there an attribute to attach to this statement that can keep it from being removed by auto-formatting techniques?
EDIT
My mistake in the description. The service reference could not be updated because the service itself could not start. When attempting to start it, and error in the Event Viewer stated that the service could not be started due to new properties of the class not being serializable. The class being the first one to attempt serialization - fix or remove the code in question and the next class would appear in the next error log. I discovered, by examining other classes, that the difference between those not being serializable and one being serializable was the classes that couldn't were missing the line: using System.Runtime.Serialization;

Context has null properties when entities in another project

I'm using EF, and I generated two tt files. I left the context.tt in the ServerComponents project. I moved the entities .tt file to a Common project, to be shared by all projects in the solution. The problem is that all of the properties/entities within the context object are null at runtime, and I can't figure out why. It's like my context.tt doesn't know where the new entities are, but I don't know how to fix that. Does anyone know what I'm missing?
Here is the server project:
Here is the common project:
And this is the state of context at runtime:
I've tried too many things to list here. I'm hoping someone just knows this answer...
I think I got it. Through trial and error, making the CustodianEntities properties public worked (they were internal). This is in DataCustodianContext.context.cs. Now I just need to alter the tt file to make sure it keeps these public when generated again.
I considered deleting this question, but I'm hoping maybe this helps someone else.

Linking assemblies with partial classes

I have a common project called common. Inside is a class called ExtensionMethods which is used by legacy applications. I want to break apart the class into multiple files, but keep the name the same. So instead of public static class ExtensionMethods {} I have many public static partial class ExtensionMethods {}.
When I drop the new dll created from the partial classes, I am getting a Method not found: exception by one of the legacy applications using the dll. What is causing this? Is the filename infomation embedded in the dll somehow? Do partial classes make the old and new dll incompatible? What's the deal? The dll is not versioned, and we are not using the gac. It's just a simple dll placed in the same directory as the exe.
Update:
Thank you everyone for the suggestions so far. Here's what I've checked so far
same namespace: check.
same signatures: check.
still public: check.
I can build the legacy app and it builds without error.
Yes, the exception tells me what method it is. Method not found:
'System.Collections.Generic.IEnumerable\`1<!!0> CompanyName.Common.ExtentionMethods.Distinct(System.Collections.Generic.IEnumerable\`1<!!0>, System.Func\`3<!!0,!!0,Boolean>)'.
(Sadly, the misspelling of 'Extension' is the way it is in the code.)
I will begin using some tools suggested by you all to look further.
Answer: User error. The dll I thought I copied wasn't the new dll I thought I was building. I can't figure if it was a rebuild that was needed or a source control problem or just my mistake. Anyways, both answers below were correct, partial classes wasn't the problem, and both answers were helpful, but in the end, I think it was the reflector solution that lead me to finding the problem. Thanks everyone.
Partial classes are a compiler trick, nothing more - there's no meaningful difference in the final assembly.
So, I think that your actual problem lies elsewhere.
Check the details of the exception you're getting and review the source for that particular method.
Also, grab an inspection tool like Reflector or dotPeek to search for the class/method in the assembly itself and you should find the problem fairly quickly.
Assuming all the classes are declared in the same namespace, it should be absolutely fine. Check:
That the classes are all in the same namespace (so you've only got one class with that name in the resulting assembly, rather than multiple classes in different namespaces)
That your method signatures are exactly as they were before - the parameter types, method names etc can't change
That the methods are still public
What happens if you try to build the legacy application against your new DLL? That should show the method being missing at compile-time, which should give you a hint about where you're going wrong. Mind you, presumably the "Method not found" exception should tell you which method isn't being found anyway...

Odd problem unit testing internal classes with VS 2008

I'm starting a project which is broken up over multiple VS projects and I was planning on having separate testing projects for each of the projects, so I'd have a solution like this:
Project1
Project1.Test
Project2
Project2.Test
There are some internal classes which I want to have tested. So I used Visual Studio 2008 (SP1) to generate the test stubs in my test project and added the InternalsVisibleTo. But I get a red squiggly line under the internal class. If I compile I get a successful build, and looking at the test method the red squiggles are gone.
But if I tough the file the squiggles come back and I have no intellisense on the internal class.
The internal is within Project1 and the test is within Project1.Test. For completeness I decided to do the exact same manner of generating the test method but this time into Project2.Test, and this time it's shown to be completely working. I don't get red squiggles, I get intellisense, everything.
I've tried deleting Project1.Test and recreating the test method, everything I can think of, but no matter what I do I can't get the internal to be completely visible within its paired Test project, only in the one which is designed to be for another project.
It's doing my nut that it's not working!
I've seen this too, especially when using strong names. To be honest, I didn't get excited; as long as it compiles and tests correctly, I can live with the odd glitch. For example, if you get one build problem, I've seen it complain that it can't find the other (internal) methods - but a clean build shows no errors. Again, I'm not to bothered by this... (maybe I'm too forgiving?).
In particular, it is only rarely that I need to use an internal type/member in the tests (most of the time I'll try to test via the public API); so the lack of 100% reliable intellisense isn't usually a big problem. I already know the type/member I am looking for (copy/paste ;-p).
Sure, it would be nice if it was fixed, but if I was the budget manager, I could probably live with it and focus on other features first.
Could you be using a string constant or something other than the exact literal stirng (without concatenation) in your InternalsVisibleTo attribute? We had the habit of using a string constant to define it, and that works fine for everything except intellisense. Replace by pasting as a simple string and it works.
Deleting your .suo file (same folder as your solution file) might help as well.
It might be a problem with IntelliSense DB file. Try to delete it and have VS try and rebuild the DB.
To do this close the solution and delete (all?) .ncb files. To be on the safe side, just rename them to something like .nc4 or whatever. Reopen the solution and rebuild it. Let me know if it works.
EDIT: Apparently, ncb files are only for C++ projects. I don't know where the IntelliSense DB for C# projects are, nor could I find out. If I were you, I would still try to find a way to reset the DB.
Asaf

Categories

Resources