How can I persist an HashMap<String, String>? - greendao

How do you persist an HashMap in greenDAO and how do you generate the respective entities?
I have read the documentation twice going forward and backward but nothing there.
Google wasn't of any help either.

You should create an Entity with a String-primary-key and a String-proerty for the value:
Entity mapEntity = schema.addEntity("Map");
mapEntity.addStringProperty("key").primaryKey();
mapEntity.addStringProperty("value");
Maybe some other attributes for the properties are needed (depending on your needs) like unique, notNull.
If you want to store your Map inside an entity, that's not quite as simple:
Basically you create an entity like this for storing all Maps:
Entity mapEntity = schema.addEntity("Map");
mapEntity.addLongProperty("id").primaryKey().autoIncrement();
mapEntity.addStringProperty("key").unigue().notNull();
mapEntity.addStringProperty("value");
and then create a relation toOne() or toMany() to reference the corresponding map.
P.S. Maybe you should choose other names than key and value. These variable names are used often and may produce conflicts in greendao.

Related

Avoid entity duplication with Linq in ASP.NET Core Web API

I want to know the best way of avoiding entity duplication in an ASP.NET Core Web API project.
Imagine that you have a product with a name and manufacturer and you want to make sure if the name is not duplicated. Imagine that a new product with a name came from client (dto) and we need to look if the name (entity) already exists in the database (using EF).
You need to trim the name (name.trim()) for both names from entity and dto
You need to remove all the whitespaces in between (string.replace(" ", string.empty())
You need to change everything to lower case (string.lower())
Finally you need to compare these two
Is there any best practices how to do this without writing all the code? I tried to use string.compare with the compareoptions like ignorecase and ignoresymbols and also the string.equal() with ignorecase option but the EF gives me an alarm that it can not translate the code.
br
I have a suggestion for your approach.
Introduce another column (This can be a primary key with other keys) and save the name with trimming and lowercase when you insert a new record to that table.
Example:
Original Name : Amir Masoud Babaei -->
New Column value: amirmasoudbabaei
And when you insert a new record, do your trimming and lowercase changes and save it to the database. Since it is a primary key, it should throw an error.
So with this approach, you don't need to loop through all the names and validate if the name is already exist.

In Objectify, how do you load an entity by ID without knowing the parent key?

I have an entity group in objectify, typical SomeParentClass and SomeChildClass. I want to do something like this to load an instance of SomeChildClass from the datastore.
ofy().load.type(SomeChildClass.class).id(idOfSomeChildClassInstace);
This is returning nothing found. Seems that you need to know the parent of SomeChildClass to get it from the datestore. This I know works.
Key<SomeChildClass> k = Key.create(someParentClass.generateKey(), SomeChildClass.class, idOfSomeChildClassInstace);
ofy().load().key(k).now;
What if I want to load an instance of SomeChildClass without knowing the parent, by just having the id of SomeChildClass.
You cannot do that - the actual full identifier of an entity is the kind and id of each of its ancestors as well as it's own kind and id. That is why building the full key works, but using just the child entity id does not. Another way of looking at it that ids are only unique between siblings of the same parent.
The easiest way to solve your issue is to produce a key for your child entity, then get the 'web safe string' for it. This string contains all the information of the entity and all it's parents and can be used to fully reconstitute the full id.
Using objectify:
String websafeKey = Key.create(parentKey, Entity.class, id).getString();
Key<Entity> key = Key.create(websafeKey);
You can also do this with the low level api if you need to.
You need to know the whole Key to be able to get() an entity. A child key consists of: kind, ID and parent key. So you need to provide all three.

Entity Framework - adding the same entity twice in many-to-many relationships

Ok. So here is the deal. I have two entities - "Product" and "Parts". The product consists of parts. And parts are reusable in other products. The relation between those entities is many-to-many. And it all works great.
The problem is that I cannot add the same part to the same product twice. EF seems to force all the related entities to be unique. Consider the following code:
var product = context.Create<Product>();
var part = GetSomePart();
Console.WriteLine(product.Parts.Count); // will output 0
// Add a part
product.Parts.Add(part);
Console.WriteLine(product.Parts.Count); // will output 1
// Add the same part again
product.Parts.Add(part);
Console.WriteLine(product.Parts.Count); // will output 1!
So ok, I get the point - avoid duplicates or something. But I need this to be possible. Is there a way to do this (to tell EF to stop enforcing unique values) without creating an additional table? Or is the only way to resolve this is to manually add the intermediate table and handle the many-to-many myself?
In this case you will have to create another table called "ProductParts" which will have an identity unique key, and which can hold references to both product and part, and they can be multiple too.
In the second add statement it will not add another object because part is already in added state. So you need to create a new object with same properties add it again.
product.Parts.Add(new Part{someProperty=part.someProperty ... ect });
if you want to reduce code you can use Automapper ( http://automapper.codeplex.com/ )to copy all properties,
product.Parts.Add(Mapper.Map<Part,Part>(part));

Entity framework 4 model first using money value object

I want to use a Money value object in my application. I have found several examples of a Money datatype. But I can't figure out how to use them with EF4. I would like to store each amount as a Decimal/CurrencyCode pair (where currencycode is a string - "USD", "SEK", etc) in the database. I tried creating a complexType but I couldn't get that to work. Is this possible?
It should be definitely possible. Your complex type is just pair of decimal and string property. It is exactly what complex type are used for. Depending on your approach you must do:
Database first:
You will define your database first. Your table will contain money and varchar columns representing your new type. When you update your EDMX model from database it will include it as scalar properties to your entity. You must remove those properties. Then go to model browser and create new complex type. Return back to entity and add complex property of your new complex type. And at the end you must go to entity mapping and map your complex type to those database columns.
Here is basic tutorial from MSDN but from unknown reason they didn't include such elementary details like screenshots. Here is some video from channel9.
Model first:
This is similar to database first but you don't have to deal with database creation and mapping. It will be generated for you.
Code first (EF 4.1):
You must create separate class for your complex type and use it as property in your entity. You should not need to map it by default - mapping should be infered. If it doesn't work you can map complext type either by using ComplextTypeAttribute annotation or by defining mapping in DbModelBuilder.
I can further extend approach you need to use if you provide more details.

Access the property used in mapping entity to a table in EFv4

When we have two entities in EFv4 EDM diagram and only one table for both in the database (for instance, having table Documents and entities Invoice and Qoute), table Documents having documentTypeId column as a discriminator and set this column as a discriminator in the EDM (in Table mappings), how do we read the value of this property in our code?
We cannot assign values to it because EF does it for us under the hood (based on what we entered in Table mappings for condition) but somehow I don't get it why we are also not allowed to read it.
Imo this property is already mapped so you can't map it again. It is used to determine type of materialized entity. Why do you need such column. Usually it is enough to use is operator like:
var document = context.Documents.GetById(id);
if (document is Invoice)
{
...
}
If you only need to select subtypes you can use OfType extension method like:
var invoices = context.Documents.OfType<Invoice>().ToList();
You also don't need to set this value when adding new entity because you are adding subtype - Invoice or Quote.
Edit:
As I understand from your comment you don't need this information in query. In such case you don't need to map it. Simply use partial class of your entity and add custom property which will return your string. Sound like stupid solution but actually it would be the easiest one.
Discriminator column should be part of mapping metadata so in case of T4 template generating your entities, it could be possible to update the template so it generate such property for you.
You may want to use a single-table inheritance hierarchy, as described here.
That way, you could have an abstract Document class that includes a DocumentTypeId column. Invoices and Quotes would extend this class, but specify certain DocumentTypeId filters. However, because the original class has a DocumentTypeId column, they would each have that column as well.
Another advantage to this approach is that you could create utility methods that can act on any Document, and you could pass any Invoice or Quote to these methods.