Is there a way to create a lazy custom property with NHibernate? - nhibernate

I have a custom property (to binding in a Grid) like that :
public class MyClass
{
public virtual IList<clsClass2> MyList{ get; set; } //Lazy loaded
public virtual string CustomProperty //To use on Grid Binding
{
get
{
if (!MyList.IsNullOrEmpty())
return MyList.Select(__comp => __comp.Name).ToList().ToString(", ");
return string.Empty;
}
}
}
Its working fine... But that way everytime I load a MyClass object, its load every MyList element because of the CustomProperty...
Is there a better way to do that?
Thanks

public virtual string CustomProperty //To use on Grid Binding
{
get; private set;
}
// using FLuentMapping
Map(x => x.CustomProperty).Formula("(SELECT ... FROM Class2Table c2 WHERE c2.MyClass_id = Id)");
and exchange ... with your database syntax of aggregating the string see here

Related

Selenium Dynamic Selectors for WebElements

I am building a testing framework, my objective is to test many websites that have similar pages with light difference between each other using this framework.
I have an issue where I want WebElements Selectors to be dynamic, which means that I want to pass the way I want to find the element as a parameter to FindElement method.
I am trying to build something like this:
public class WebComponent
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IWebElement WebElement{get;set;}
public Accessor Accessor { get; set; }
public WebComponent()
{
Accessor = new Accessor();
}
}
public class Accessor
{
OpenQA.Selenium.By By { get; set; }
public string Value { get; set; }
}
And later in my code when I want to have instance of this class:
WebComponent component = new WebComponent();
component.ID = 1;
component.Name = "Logout Button";
component.Description = "The button to click when user wants to logout of website";
component.Accessor.By = By.Id;
component.Accessor.Value = "logout";
component.WebElement = Browser.Driver.FindElement(//missing code);
My question is how can I find the WebElement using component.Accessor, any advice or suggested edits will be much appreciated.
By.Id is a method group, you can't assign it to type OpenQA.Selenium.By. The assignment should be
component.Accessor.By = By.id("logout"); // or any other By and value.
And then you can locate the element using
component.WebElement = Browser.Driver.FindElement(component.Accessor.By);
Edit
To choose the locator and value dynamically you can do something like
private By chooseType(String locatorType, string value) {
switch(locatorType) {
case "id":
return By.id(value);
case "class":
return By.className(value);
//...
}
}

How to map object type field in Nhibernate Auto Mapping

When trying to map, I got this error:
Association references unmapped class: System.Object
My class:
public partial class MessageIdentifier
{
public virtual int ID { get; set; }
public virtual object Item { get; set; }
}
And the convention:
public class MyUsertypeConvention : IPropertyConvention
{
public void Apply(IPropertyInstance instance)
{
if (instance.Type.Name == "Object")
instance.CustomType<string>();
}
}
Kindly suggest how to map?
As a simple (quick, naive) solution - I would suggest to create and map real string property. And then let your setter and getter (or some AOP or listener) to do the "to/from string conversion":
public partial class MessageIdentifier
{
public virtual int ID { get; set; }
public virtual object Item
{
get { return ... my conversion from string; }
set { ItemString = ...my conversion to string; }
}
public virtual string ItemString { get; set; }
}
A smart and preferred (but a bit more challenging) is to create CustomType - which will hide that conversion and support REUSE. Check e.g. here
NHibernate Pitfalls: Custom Types and Detecting Changes
Creating and Testing a Custom NHibernate User Type
Not a satisfactory answer. It doesn't work with class that is generated from xsd by using XML. You can try the following:
public partial class MessageIdentifier
{
public virtual int ID { get; set; }
private object itemField;
public object Item
{
get { return this.itemField; }
set { this.itemField = value; }
}
}

Delegate the property display name translation to a handler

Current code in model:
[Display(Name = "E-mail")]
public string EMail { get; set; }
Desired code:
public string EMail { get; set; }
I would like to delegate the translation to a handler, something like this:
if(propertyName == "EMail") return "E-mail"
Based on my understanding of your question, I'm assuming that you are trying to implement localisation in your application.
If so, there are two options;
Resources
In .NET you can add Resource (.resx) files into your application to handle translation (one resx for each language). Then you can specify the Resource by specifying the ResourceType property of your Display attribute. For example;
public class Model
{
[Display(Name = "Email", ResourceType = typeof(Resources.Strings))]
public string Email { get; set; }
}
Custom attribute
Alternatively, if you are set on implementing this in a handler then you could implement a custom attribute, as demonstrated in this question.
Edit: Modified from the example in the above post.
If you add a new Resource file to your project - say Strings.resx and add "HelloWorld" as a field. You can then create a new attribute, such as LocalisedDisplayNameAttribute;
public class LocalisedDisplayNameAttribute : DisplayNameAttribute
{
public LocalisedDisplayNameAttribute(string resourceId)
: base(GetMessageFromResource(resourceId))
{
}
private static string GetMessageFromResource(string resourceId)
{
// "Strings" is the name of your resource file.
ResourceManager resourceManager = Strings.ResourceManager;
return resourceManager.GetString(resourceId);
}
}
You can then use it as follows;
public class Model
{
[LocalisedDisplayName("HelloWorld")]
public string Email { get; set; }
}
Let me know if I can help further,
Matt

Why HashedSet forces loading lazy collection?

I query items with lazy collections in via nHibernate. Items are queried without fetching collections. But when i try to create HashedSet
var hashedSet = new HashedSet<Thing>(Session.Query<Thing>())
from those items all lazy stuff is fetched. Whats causing that?
[Serializable]
public class Thing {
public virtual String Name { get; set; }
public Thing() {
OtherThings = new HashedSet<OtherThing>();
}
public virtual ISet<OtherThing> OtherThings { get; set; }
}
Maybe you have overridden GetHashCode() in the entity (or any base class of it) and access the properties there?

Fluent nHibernate and mapping IDictionary<DaysOfWeek,IDictionay<int, decimal>> how to?

I have problem with making mapping of classes with propert of type Dictionary and value in it of type Dictionary too, like this:
public class Class1
{
public virtual int Id { get; set; }
public virtual IDictionary<DayOfWeek, IDictionary<int, decimal>> Class1Dictionary { get; set; }
}
My mapping looks like this:
Id(i => i.Id);
HasMany(m => m.Class1Dictionary);
This doesn't work. The important thing I want have everything in one table not in two. WHet I had maked class from this second IDictionary I heve bigger problem. But first I can try like it is now.
It's not currently possible to use nested collections of any type in NHibernate.
Instead, you should define your property as follows:
public virtual IDictionary<DayOfWeek, Class2> Class1Dictionary { get; set; }
And add a new class:
public class Class2
{
public virtual decimal this[int key]
{
get { return Class2Dictionary[key]; }
set { Class2Dictionary[key] = value; }
}
public virtual IDictionary<int, decimal> Class2Dictionary { get; set; }
}
This way, you can map both classes and dictionaries normally, and still access your dictionary as:
class1Instance.Class1Dictionary[DayOfWeek.Sunday][1] = 9.4