Mapping an Array of custom objects using fluent nhibernate - collections

I have two classes, File and SearchResults. ShearchResults has an array of files. The relation between them is ManyToMany. This is how i mapped the relationship:
HasManyToMany<File>(x => x.Files).Table("refSearchResultsFiles").ParentKeyColumn("[SearchResult]").ChildKeyColumn("[File]");
When i try to save a SearchResult object, i get this exception:
Unable to cast object of type 'NHibernate.Collection.PersistentBag' to type 'TankusFileSharingClassLibrary.Entities.File[]'.
Why is this?

you are missing .AsArray(...) in the hasmanytomany

Related

Dart - Casting List<SuperType> to List<SubType> using generics

I am new to Flutter and Dart, coming from native Android.
Android has a very nice database abstraction architecture called the Room Persistence Library. As far as I am aware, no such database abstraction architecture exists for Flutter using the MVVM / MVC design patterns.
My solution was to create a Dart version of it myself. I got it pretty much done after a few headaches, but I cannot seem to get LiveData to work properly using generics.
I set up my class like this:
class LiveData<T> {
...
}
Now when I want to return some data, it can either be an Object or List<Object>. I found a neat hack for differentiating the two from T:
...
// Parse response
// This checks if the type is an instance of a single entity or a list.
if (entity is T) {
cachedData = rawData.isEmpty ? null : entity.fromMap(rawData.first) as T;
} else {
cachedData = rawData.map((e) => entity.fromMap(e)).toList() as T;
}
...
The problem lies in the second block:
cachedData = rawData.map((e) => entity.fromMap(e)).toList() as T;
With the error:
- Unhandled Exception: type 'List<Entity>' is not a subtype of type 'List<Vehicle>' in type cast
The question then becomes: How can I cast Entity to Vehicle when I do not have access to the Vehicle class. Only an instance of it is assigned to an Entity entity variable.
Here's a snippet to demonstrate my access to Vehicle:
final Entity entity;
...assign Vehicle instance to entity...
print(entity is Vehicle) // True
I've tried using .runtimeType to no avail. I have also thought about splitting LiveData into two classes, the second one being LiveDataList. Although this seems to be the easiest solution to not bug the code- it would bug me (bad pun is intentional) and break the otherwise pretty direct port of Room.
As a temporary solution, I have abstracted out the build logic into a generic function to be passed to the LiveData in the constructor.
final T Function(List<Map<String, dynamic>> rawData) builder;
And now I call that instead of the previous code to build the cachedData.
// Parse response
cachedData = builder(rawData);
With the constructor for the LiveData<List<Vehicle>> called when accessing all vehicles in the Dao<Vehicle> being:
class VehicleDao implements Dao<Vehicle> {
...
static LiveData<List<Vehicle>> get() {
return LiveData<List<Vehicle>>(
...
(rawData) => rawData.map((e) => Vehicle.fromMap(e)).toList(),
...
);
}
}
In Dart (and indeed in many languages) generics screws with the concept of inheritance. You would think that if Bar inherits from Foo, that List<Bar> would also be castable to List<Foo>.
This is not actually going to be the case because of how generics work. When you have a generic class, every time you use that class with a different type, that type is treated as a completely separate class. This is because when the compiler compiles those types, class MyGenericType<Foo> extends BaseClass and class MyGenericType<Bar> extends BaseClass are basically converted to something like class MyGenericType_Foo extends BaseClass and class MyGenericType_Bar extends BaseClass.
Do you see the problem? MyGenericType_Foo and MyGenericType_Bar are not descendants of one another. They are siblings of each other, both extending from BaseClass. This is why when you try to convert a List<Entity> to List<Vehicle>, the cast doesn't work because they are sibling types, not a supertype and subtype.
With all this being said, while you cannot directly cast one generic type to another based on the relationship of the generic type parameter, in the case of List there is a way to convert one List type to another: the cast method.
List<Entity> entityList = <Entity>[...];
List<Vehicle> vehicleList = entityList.cast<Vehicle>(); // This cast will work
One thing to note though, if you are casting from a supertype generic to a sub-type generic and not all the elements of the list are that new type, this cast will throw an error.

JMS Serializer deserialize ArrayCollection of Objects

I have serialized ArrayCollection with Objects, everything is serialized into json with jms/serializer-bundle.
When I want deserialize my collection with keys (it's important):
deserialize($data, 'ArrayCollection<int, FooBundle\Entity\Item>', 'json');
I get array. But when I make new ArrayCollection with results:
new ArrayCollection(deserialize($data, 'ArrayCollection<int, FooBundle\Entity\Item>', 'json'));
Everything is fine and I get ArrayCollection with Objects and all keys are kept. Maybe someone knows why 1st method doesn't work?
Jms serializer has possibility to deserialize into ArrayCOllection f Objects section #Type here: http://jmsyst.com/libs/serializer/master/reference/annotations
Only solution that I found was creating separate class with items (ArrayCollection type) field. Here is jms-serializer definition for this class:
FooBundle\Entity\Cart:
exclusion_policy: ALL
properties:
items:
expose: true
type: ArrayCollection<int, FooBundle\Entity\CartItem>

How to serialize object that is not a personal model with JMS Serializer?

I am using FOSrestBundle in my Symfony2 project. I have a view created like this:
$view = $this
->view(array(
'form' => $this->formHandler->getForm()->createView(),
'translation' => $translation,
), Response::HTTP_OK)
->setTemplate('MyBundle:Translation.html.twig');
Where $translation is an object of my own bundle. The thing is when I call the $this->handleView($view), FosRestBundle use JMS serializer to serialize the data of my view (the form and the translation object) but my translation object have a lot of attributes useless in my case and the response is far too big for what I am trying to do.
I decide to use the group annotation to only retrieve useful attributes.
Here is the context with the view group:
$context = SerializationContext::create()->setGroups(array('view'));
$view->setSerializationContext($context);
And in my Translation model I can set the ExclusionPolicy to all and add usefull attributes to the view group. It is working but with this configuration (the group view in the serialization context) my form object (which is a Symfony\Component\Form\FormView) is serialized to {}
How can I use a group for my Translation model but still serialize my FormView object ?
If you're using annotations the JMS serializer has exclusion policies for each class, which you can see here.
I would suggest instead to default to exclude all and add the serializer groups annotation on only properties you want to expose. You can add multiple groups, so in this case your serializer context could have the groups "form" and "translationBasic", then add the "form" group to all properties on formView and "translationBasic" to just those you want on the Translation class.

How to convert linq entitySet AND CHILDREN to lists?

I ran into an error when trying to serialize a linq entitySet. To get around this i converted the entitySet to a list. The problem I have run into now is that it's child entity sets are not converting to a list and when I try to serialize the parent those are now throwing an error. Does anyone know of a way to convert a linq entitySet AND it's children to lists?
p.s. I'm new to linq so if any of this dosn't make sense let me know
Just project onto new types:
var q = from e in Entities
select new
{
Id = e.Id,
Name = e.Name,
Children = from c in e.Children
select new
{
Id = c.Id,
Name = c.Name,
// etc.
},
// etc.
};
var s = serializer.Serialize(q);
I am guessing you are trying to serialize to XML.
Either way, the problem stems from the circular references in LINQ entity objects. Lets say you have a main table Customers with a second table Orders. The Customers entity has a reference to all of the Orders this customer has (typically Customer.Orders). The Orders entity has a reference to the customer entity (typically Order.Customer). When the serializer tries to serialize this object, it recognizes the circular reference and throws an error.
In order to do what you want, you have to write your own serializer or convert the objects to something that can be directly serialized, like custom serialization objects which contain just the information you want to show up in the serialized version.

How do I create an instance of a class in an ASP.NET application

How do you go about creating an instance of an object when given the class name as a string in an ASP.NET v2 application? For example, I've got a class called SystemLog defined in the app_code section of the application. The class is defined within the Reports namespace. To create an instance of the object, I do something like this:
Dim MyObject As New Global.Reports.SystemLog
However, I want to create this object using a string to define the type. The type name is stored in a SQL database as a string. I thinks it's probably something to do with Activator.CreateInstance(AssemblyName, TypeName) but what I don't know is what to pass in those strings. What is the assembly name of an ASP.NET web app?
Help!
Thanks, Rob.
PS. I don't want a hard coded Select statement :-)
string typeName = "Your Type Name Here";
Type t = Type.GetType(typeName);
object o = Activator.CreateInstance(t);
This will give you an instanciated type. If will be up to you to cast it to the correct type and call your appropriate methods.
If you need to create a type that doesn't have a parameterless constructor there is an overload on CreateInstance that takes a params of objects to pass to a constructor. More info at this MSDN article.
The following is able to create type, even if it's from another assembly:
public object CreateInstance(string typeName) {
var type = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => t.FullName == typeName);
return type.CreateInstance();
}
You can use this to get it from a particular assembly:
Assembly assembly = Assembly.Load("myAssembly");
Type ObjectType = assembly.GetType("Type name here");
then.....object o = Activator.CreateInstance(ObjectType);

Resources