Entity Framework 4: Image type? - entity-framework-4

I am creating an Entity Data Model for a document. I want to store the body of the document as a BLOB--document bodies will be larger than the varbinary max. As I understand things, what I need to do is create a property of type Image to store the document body.
Here's my problem: The types listed in the Properties pane do not include an Image type:
Does EF4 recognize an Image type? If so, how do I create an entity property of type Image? Thanks for your help.

Image is deprecated, you should use varbinary(MAX) instead - but if you are using files larger than 2GB (as you apparently are since varbinary(MAX) would otherwise be sufficient) you probably should bypass this altogether and save them on disk - with plain SQL Server 2008 I'd suggest a filestream.
According to this article this approach will also work for Entity Framework (although the article refers to an older EF version and I haven't tried it personally)

varbinary(max) is replacement of Image type. The storage size of varbinary(max) is 2^31 - 1 Bytes => 2GB. it should be enough. Image type is deprecated and will be probably removed in future version of SQL server. Use Binary type for your data and set its length to Max.
Btw. working with such amount of data in EF can be quite bad idea.

Related

Genexus Extensions SDK - Is there a built in helper to save data locally?

I Would like to know if the Genexus Extension SDK already implements something to store persistent data locally (KB Independant and per KB), something like PersistentDictionary from ManagedEsent
I know that genexus uses SQL Server to store KB Related information, is there an interface for me to extend that?
I want to save data per genexus instance (locally) and use that data to load my extension config, everytime the users executes Genexus.
We don't use PersistentDictionary. I would advice not to use it, as it's a Windows specific API, and we are trying make everything new cross platform, as part of our journey of making GeneXus BL run on other OS.
There are different options of persistence, depending on the specific details of your scenario.
If you want to store something like configuration settings for your extension, you can use the ConfigurationHelper class located in Artech.Common.Helpers. This class provides read access to the configurations defined in the GeneXus.exe.config file in the GeneXus installation folder, as well as read/write access to the Environment.config file located in %AppData%\GeneXus\GeneXus\<version>\Environment.config. Note this file depends on the current user, and is shared between different GeneXus instances of a same main version.
The ConfigurationHelper class provides operations to read and save settings of basic types string, int and bool.
const string MY_EXTENSION = "MyExtensionSettings";
const string SETTING1 = "Setting1";
const string SETTING1_DEFAULT_VALUE = "This is the default value";
const string SETTING2 = "Setting2";
const int SETTING2_DEFAULT_VALUE = 20;
string setting1Value = ConfigurationHelper.GetUserSetting(MY_EXTENSION, SETTING1, SETTING1_DEFAULT_VALUE);
int setting2Value = ConfigurationHelper.GetUserSetting(MY_EXTENSION, SETTING2, SETTING2_DEFAULT_VALUE);
// Do something and maybe change the setting values
ConfigurationHelper.SetUserSetting(MY_EXTENSION, SETTING1, setting1Value);
ConfigurationHelper.SetUserSetting(MY_EXTENSION, SETTING2, setting2Value);
If you want to store something in a file based on the current opened KB, there's no specific API that'll help you handle the persistence. You can use the properties Location and UserDirectory of the KnowledgeBase class to access the KB location or a directory for the current user under the KB location, but it's up to you the handling of the file. You'll have to decide on the file format (binary or text), file encoding in case of text files, and handle all read and write operations to that file.
We use the kb.UserDirectory path to store non-critical stuff, such as the set of objects that were opened the last time the KB was closed, or the filter values for different dialogs.
In case you'd like to store settings inside the KB, there are plenty of options.
You can add properties to existing objects, KB version or environment. Making it a property doesn't necessary mean you'll have to edit the value in the property grid, although it's usually the way to go.
You can define a new kind of entity. Entities are the basic elements that can be stored in a KB. The entity may be stored depending on the active version of the KB, or may be independent of the current version. Entities can have properties, whose serialization is handled by the property engine, and also can read and store a byte array whose format and content will be handled by you.
You can add a part to an existing object. For instance you may want to add a part to Procedure objects. In order to do this you'll have to extend KBObjectPart, define your part in a BL package, declare that the part composes objects of certain type, and provide an editor for your new part in a UI package. KBObjectPart extends Entity so the serialization of the part is similar as in the previous case. A caveat of this option is that you'll also have to handle how the part content is imported, exported, and compared.
You can add a new kind of object. Objects extend the KBObject class, which extends Entity. Objects are not obliged to have parts (for instance the Folder object doesn't have any). When choosing to provide a new kind of object you have to consider a couple of things, such as:
Do you want to be able to create new instances from the new object dialog?
Will it be shown in the folder view?
Can it be added into modules?
Can it have the same name as other objects of different types?
As a general guideline, if you choose to add a new property, add it to objects, versions, or environments, not parts. Adding properties to parts is not so good for discoverability. Also if you choose to add a new kind of object, even though it inherits from Entity which as mentioned earlier can read and store a byte array, it's preferred to don't use the byte array in KBObject and add a KBObjectPart to it instead. That way the KBObject remains as lightweight as possible, and loading the object definition from the DB remains fast, and the blob content is loaded only when truly needed.
There's no rule of thumb. Depending on the specifics of the scenario, one option may be more suited than others.

TFDTable/TFDQuery on blob null - provide alternative image

Is there a way to configure my TFDTable/TFDQuery such that whenever BLOB in a table record is Null,
i have a chance to provide another Blob/photo.
I looked through TField events for blob, but there seems to be no suitable event.
Setup: Delphi 10.4, MySQL, using FMX framework
Add a CalcField or InternalCalcField to your dataset and in the OnCalcFields() handler check if the blob field is empty. In that case, fill with your 'alternative' data.
Then in the rest of your application refer to the InternalCalcField field instead of the original one.
You do not specify where that data should come from, so you'll have to figure that out yourself.

Property in Entity partial class

I have an entity/table that uses sqlgeography.
Since EF 4.X doesn't support spatial types I'm instead sending the bytes of the field back and forth.
I have stored procs on the database side that handles the converstion and properties on the code side to do that job.
To add the properties in the code I used a partial class.
One of those properties is for the SqlGeography which simply wraps around the byte[] property to handle getting and setting.
This property is hidden from EF using the NotMappedAttribute.
The other is the property exposing the byte[] itself and is decorated with the EdmScalarPropertyAttribute and DataMemberAttribute.
I then go to the EF model designer (*.edmx) to point the entity model at the Insert/Update/Delete stored procs.
It finds the stored procs alright and realises that they (when appropriate) take a VARBINARY parameter.
It also has a drop down allowing you to select a property on the entity class which maps to that parameter.
However this drop down doesn't list either of my properties. I don't care about the SqlGeography property since that is meant to be hidden from EF, however it is vital for me to be able to point it at the byte[] property, as that is where the data comes from.
I would very much like to avoid database triggers or wrapper classes and addiitonal fields to fudge this in to working.
I tried manually editing the .edmx file to include the byte[] property, but then it just complains it's unmapped.
Can anyone give me some insight in to how to get this to work? Or an alternative method of achiving the end result?
We could use a view to create the binary field for us, but this then involves manually creating a lot of the xml for the relationships within the data.
This pretty much voids the point of using EF which is to make life simple and easy.
For this project We'll just add a binary field to the table then have sprocs to handle the converstion on the server and a property in a partial entity class for exposing the geography type in the model.
Next project I doubt we'll be using EF. Dapper is so much more painless, even if theres a touch more code writing involved.
Here's the links for using views if anyone thinks it would be applicable to them:
http://thedatafarm.com/blog/data-access/yes-you-can-read-and-probably-write-spatial-data-with-entity-framework/
http://smehrozalam.wordpress.com/2009/08/12/entity-framework-creating-a-model-using-views-instead-of-tables/
In the end we created a computed column for each table that exposes the spatial data as bytes.
We then use stored procs for inserting and updating the spatial data.

How to write object in file in java without using object serialization?

I want to write object to file. But as per my study I found that it is not possible without object serialization. Other way is to convert object to array of bytes and then to write to file. But for this also object serialization is required. Is there any other way to write object to file? Because I want to use the same code in android and blackberry also. Please help me, I want to solve this problem as early as possible. Thanks in advance.
If you want to write an object to a file, then you by definition want to serialize it - that's what serialization means. If you're just looking for a way to save data to a file that doesn't rely on device-specific storage mechanisms, then you will need to write some custom serialization code. For every class that you want to store in a file, you'll need to do the following:
Write a method that stores the current state of the object in some writable structure, such as a string or byte array
Write a method that converts the string or byte array back into an object (it will probably be easiest to have this method take a stream as a parameter, and have it create a new object based on the data in that stream)
For example, you could save objects as XML or JSON strings, or in more efficient means - the best way to store it mainly depends on what sort of data you are storing and what you need to do with it.
It is good practice when doing this to include some version number that defines what version of the class you are using, and include this first when serializing the object. That way, when you deserialize, you can check that version number and know how it was serialized. This makes it easy to change your serialization scheme later on while still maintaining backwards compatibility with older files.
If you are just looking for a general purpose storage mechanism that is device-independent, then you could also look into using a SQLite database - they are supported on most if not all modern mobile operating systems. This will be easier than hand-rolling your own serialization, and will also generally have better performance.

How to store a file in the database with Grails

I need to store a file in the database using Grails. So, do you know how I can do that? Which data type should I use in the domain class (byte[] might be a solution)?
See Chapter on Uploading Files in the Grails User Guide. It is also possible to use a java.sql.Blob as type for the binary content (which would be preferable when dealing with huge files).
alternatively, store the file on disk, and store the path to it in the database. it is generally faster to access that file on disk than in a db. but of course, that really just depends on your needs in the app. But be aware of this alternative.
You can force the domain object to use a specific type when updating or generating the database with column mappings:
byte[] orgFile
static mapping = {
columns {
orgFile type:'blob'
}
}
This has worked for me so far ;)
I have had the same problem. All I needed to do was to go to the database (Oracle) and change the column type from RAW to Blob. (Actually I had to remove the column and then to create a new one).
I was never able to find out how to use a "java.sql.Blob" as suggested above. I found this this (converting from bytes to Blob), but it seemed a bit complicated.
I recently used byte[] in a domain class for storing file, it was working fine until i moved my application from "HSQLDB" to "Oracle express".
On Oracle, byte[] was mapped to a raw object instead of blob... (not sure of what was exactly wrong) and I finally solve the problem by using a java.sql.blob

Resources