Fluent NHibernate - Map 2 Identical classes to same table - nhibernate

I've seen this (unanswered) question asked once before, but in a different context. I'm looking to have two domain objects map to the same table, WITHOUT a discriminator. The two classes are:
public class Category
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual ReadOnlyCategory ParentCategory { get; private set; }
}
and
public class ReadOnlyCategory
{
public virtual int Id { get; private set; }
public virtual string Name { get; private set; }
public virtual ReadOnlyCategory ParentCategory { get; private set; }
}
The main difference is that all public properties of ReadOnlyCategory are read-only. My idea here is that I want all users of this class to know that they should only mess with the category they are currently 'looking' at, and not any other categories in the hierarchy. (I've left off other properties regarding the subcategories.)
Clearly, in the database, Category and ReadOnlyCategory are the same thing, and NHibernate should treat them very similarly when persisting them. There are three problems wrapped into one here:
1) How do I do the mapping?
2) When instantiating the objects, how do I control whether I instantiate Category or ReadOnlyCategory?
3) When persisting the objects, will the mapping be smart enough, or do I need to use an extensibility point here?
Any pointers on how I can get this to happen?
(Or am I crazy?)

This looks like wrong object model design to me. I don't see a good reason to introduce a new class just for authorisation reasons (whether user allowed to modify a given category object?). You may as well use one class and throw for example InvalidOperationException if an end user is not supposed to modify a category.

Related

Confused about DTOs when reading and editing. How to desing DTO for filling the form in VUEjs app?

I am trying to develop an enterprise-level application. I have domain and application services. I have created my DTOs for multiple purposes separately. But confused about which way I should use them from the API viewpoint.
I have complex objects lets say,
public class Entity{
public int Id { get; set; }
public string Name { get; set; }
public int? ManufacturerId { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
public class Manufacturer{
public int Id { get; set; }
public string Text { get; set; }
}
And I have corresponding DTOs designed with composition now. It was separated before.
public class EntityBaseDto{
public string Name { get; set; }
}
public class EntityReadDto : EntityBaseDto{
public string Manufacturer { get; set; }
}
public class EntityWriteDto : EntityBaseDto{
public int? ManufacturerId { get; set; }
}
Now the question is,
I have a table which is filled with List<EntityReadDto> which is clear. Before, EntityReadDto also had the ManufacturerDto as fully included with id and text. Whenever I require to edit one of the entries from the table I was able to load the dropdown selected items or list of tags etc with the ids attached to the Manufacturer objects within ReadDtos. Now it is not possible. Since I wanted to simplify the codes I just converted them to strings that are read-only. Now I have created another endpoint to get an editable version of the record when needed. Ex: EntityWriteDto will be used to fill the form when the edit is clicked on a specific item. The manipulation will be carried on that DTO and sent with the PUT type request to edit the record.
I am not sure if this approach is ok for these cases. What is the best practice for this? I have many objects related to the entities from other tables. Is it ok to make a call to get an editable version from the backend or need to have it right away in a VUEjs app?

Reference another class using an index vs storing entire instance

In a class which needs to "contain information" about another class (sorry I don't know the terms for this), should I store the reference to that other class as something like an integer/id, or should I store it as an instance of the other class? What is this called, if there is a name for it?
As a very basic example, an app where we want to store what a user's favorite restaurant is:
public class User {
public int id { get; set; }
public string name { get; set; }
// id of restaurant...
// public int favoriteRestaurantId { get; set; }
// ...or entire instance of Restaurant type
// public Restaurant favoriteRestaurant { get; set; }
}
public class Restaurant {
public int id { get; set; }
public string name { get; set; }
}
Note: if you think this is off topic, please explain why this question would be allowed and is a highly rated/useful question, but mine is not: Interface vs Base class Or at the very least tell me what this is "called" so I can research it more myself. As far as I can tell from Stackoverflow's FAQ this question is on topic.
Your first variant
public int favoriteRestaurantId { get; set; }
only makes sense if you are only interested in the id and not the other attributes (name) of the restaurant object. Otherwise you will need some external container that stores all restaurant objects and have to search the container for the restaurant with the given id.
In your second variant
public Restaurant favoriteRestaurant { get; set; }
if you write
someUser.favouriteRestaurant = someRestaurant;
this also stores a reference to an existing someRestaurant. It will not copy the whole object. at least not in languages like C# and Java.
Only if you do something like
someUser.favouriteRestaurant = new Restaurant(someRestaurant);
the user will have its own copy of the restaurant object.
There are cases where this would make sense but in your example it is probably not a good idea for two reasons:
If for example the name of the someRestaurant changes, this should also change the name of favouriteRestaurant. This will not happen automatically if favouriteRestaurant is a copy.
It is a waste of memory.

Silverlight WCF reused types no methods

I feel like this should be really simple but I am having an issue figuring out what is going on. I am working with a WCF service and have "Reuse types in all referenced assemblies" on. I have some simple classes to transfer some data. The classes show up fine and all the basic members show up, but no methods do. Are methods not included in this? Do I have to specify this is what I want somehow? Here is some example code. I just switched out my names to make it a little more generic.
public class Car
{
public string CarColor { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public string GenerateId()
{
return CarColor + Model + Year;
}
}
In this example I get CarColor, Model, and Year on the client side but not GenerateId.
So I ended up doing this a little different. It totally makes sense that only the data comes over. The problem is that I didn't want to have to have a new project to hold the data types. Its just a pain to have a new repository and a completely separate project for a handful of classes. Since I really only need the methods on the client side, I am just creating partial classes with them in it on the client side. That way I can pull the data structure from the service but still extend it to have the methods I need.
Service definition
public class Car
{
public string CarColor { get; set; }
public string Model { get; set; }
public int Year { get; set; }
}
Client partial class
public partial class Car
{
public string GenerateId()
{
return CarColor + Model + Year;
}
}

Is the properties in Entity must be virtual when using FluentNhibernate?

Which entity FluentNHibernate uses as entity
I create some entity in Domain(or BLL), such as the following:
public class Role
{
public long ID { get; protected set; }
public string Name { get; set; }
public string Description { get; set; }
public List<User> Users { get; set; }
public Role()
{
Users = new List<User>();
}
}
And I want make use of FlunetNHibernate to map them, but get errors:
The following types may not be used as proxies:
Freeflying.Domain.Core.Profile: method get_ID should be 'public/protected virtual' or 'protected internal virtual'
Yes, I recall the programmer requirement when use FluentNHibernate, the entity should be like this:
public class Role
{
public virtual long ID { get; protected set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
}
But It looks wired. Do you think so? How do you do when using FluentNHibernate? I don't want go back to Domain layer and add virtual for every property.
This is a basic requirement for using NHibernate; It allows NHibernate to generate a proxy class that descends from your class for lazy loading and such.
I have not seen a method of removing this requirement, though if such a thing is possible it would mean that you could not use lazy loading of objects and/or properties.
Here's a blog post that explains this a bit more; It also offers a way to avoid marking your properties as virtual, although I would really recommend that you do not use this method (marking classes to avoid lazy loading) as the benefits of lazy loading in most circumstances far outweigh the cost of making your properties virtual.

How to structure domain model when using NHibernate Search/Lucene

I am messing around with NHibernate Search and Lucene to create a searchable index of legal entities. My domain model looks somewhat like this:
[Indexed]
public abstract class LegalEntity : AggregateRoot
{
public virtual Address Address { get; set; }
}
public class Person : LegalEntity
{
public virtual string FirstNames { get; set; }
public virtual string LastName { get; set; }
}
public class Company: LegalEntity
{
public virtual string Name { get; set; }
}
public class Address : Component
{
public virtual string Street { get; set; }
public virtual string HouseNumber { get; set; }
// etc...
}
As the subclassing implies, LegalEntity is an NHibernate entity specialized as Person and Company, and Address is an NHibernate component.
Now, how would I best go about creating a really Google-like fuzzy search that includes all the fields of a LegalEntity, including those inside the Address component?
My first idea was to implement an AddressFieldBridge to help in bringing in the fields of the Address component, and then just throw in [Field] on all the fields, but then I could not find a way to construct a FuzzyQuery as a conjuntion between multiple search terms.
My next idea was to create an abstract property tagged with [Field] on LegalEntity, like so:
[Field(Index.Tokenized)]
public abstract string SearchableText { get; }
and then have Person and Company return texts that combine names and all the fields from the Address component into one string, which would then be tokenized and indexed by Lucene.
That, however, made me feel kind of icky.
I would like to learn the best and least intrusive (from a domain model perspective) way to accomplish this task - any suggestions are appreciated :)
Take a look at my question.
Andrey created patch to specify lucene stuff outside. Syntax ain't uber clean (maybe there's some progress done on this, haven't checked), but i guess it gets job done.