How to access NHibernate.IQueryOver<T,T> within ActiveRecord? - castle-activerecord

I use DetachedCriteria primarily, it has a static method For to construct an instance. But it seems IQueryOver is more favourable, I want to use it.
The normal way to get an instance of IQueryOver is Isession.Query, and I want get it with ActiveRecord gracefully, anyone knows the way? Thanks.

First, QueryOver.Of<T> return an instance of QueryOver<T, T>, then you build conditions with QueryOver API.
After that, query.DetachedCriteria return the equivalent DetachedCriteria, which can be used with ActiveRecord gracefully.
var query = QueryOver.Of<PaidProduct>()
.Where(paid =>
paid.Account.OrderNumber == orderNumber
&& paid.ProductDelivery.Product == product)
.OrderBy(paid=>paid.ProductDelivery.DeliveredDate).Desc;
return ActiveRecordMediator<PaidProduct>.FindAll(query.DetachedCriteria);

As far as I know, there is no direct support for QueryOver. I encourage you to create an item in the issue tracker, then fork the repository and implement it. I'd start by looking at the implementation of ActiveRecordLinqBase, it should be similar. But instead of a separate class, you could just implement this in ActiveRecordBase. Then wrap it in ActiveRecordMediator to that it can also be used in classes that don't inherit ActiveRecordBase.

Related

flink assign uid to window function

is there a way to assign uid to a window function (such as apply(ApplyCustomFunction)) as we do for map/flatmap (or other) functions in Flink. The Flink version is 1.13.1.
I would like to specify the case with an example
DataStream<RECORD> outputDataStream = dataStream
.coGroup(otherDataStream)
.where(DATA::getKey)
.equalTo(OTHERDATA::getKey)
.window(TumblingProcessingTimeWindows.of(Time.seconds(2)))
.apply(new CoGroupFunction());
Thanks
CoGroupedStreams.WithWindow#apply(CoGroupFunction<T1,T2,T>) doesn't have the return type that's needed for setting a UID or per-operator parallelism (among other things). This was done in order to keep binary backwards compatibility, and can't be fixed before Flink 2.0.
You can work around this by using the (deprecated) with method instead of apply, as in
DataStream<RECORD> outputDataStream = dataStream
.coGroup(otherDataStream)
.where(DATA::getKey)
.equalTo(OTHERDATA::getKey)
.window(TumblingProcessingTimeWindows.of(Time.seconds(2)))
.with(new CoGroupFunction())
.uid("window");
The with method will be removed once it is no longer needed.
Use with() instead of apply(). It will be fixed in 2.0 version, how it sayed in documentation

ControlPath equivalent from DotNetNuke DnnApiController ActiveModule

Is there a way to get the module root folder (folder under DesktopModules) of the ActiveModule from a DnnApiController?
In PortalModuleBase I would use the ControlPath property to get to the same root folder I'm looking for.
As #MitchelSellers points out, it doesn't appear to be in the API so you have to figure it out yourself.
Since the API gives us the ActiveModule which is a ModuleInfo that's probably the best way to get at it.
If your modules use a pretty standard consistent naming then the following "best guess" method should work pretty well
public static string ControlPath(ModuleInfo mi, bool isMvc = false)
{
return isMvc
? $"/DesktopModules/MVC/{mi.DesktopModule.FolderName}"
: $"/DesktopModules/{mi.DesktopModule.FolderName}";
}
The other way is to look at the ModuleDefinitions of our module and grab the first ModuleControl and look at it's ControlSrc to see it's path.
public static string ControlPath(ModuleInfo mi)
{
var mdi = mi.DesktopModule.ModuleDefinitions.First().Value;
var mci = mdi.ModuleControls.First().Value; // 1st ModuleControl
return Path.GetDirectoryName(mci.ControlSrc);
}
The second method is really messy (and untested) but should give you the actual folder path where the controls are installed, over the other best guess method above.
From the API's it doesn't appear so, you should know the path for this though since you are inside of your module, the only concern is if you are inside of a child portal you need the prefix, which you should be able to get. I'd just use Server.ResolveClientUrl() to get it.

one to many relationship in Objectify4

I am working with GAE with java. i am just creating a sample application with Student and Course relationships. I am having many branches and many students. Each branch can have many students, i tried like
ObjectifyService.register(Course.class);
ObjectifyService.register(Student.class);
Course course = new Course();
course.setName("ss");
course.setBranch("cs");
ofy().save().entity(course).now();
Student stu = new Student();
stu.setName("student1");
Key<Course> courseKey = new Key<Course>(Course.class, course.getId()); // getting error here
stu.setCourse(courseKey);
System.out.println("saving");
ofy().save().entity(stu).now();
I am not sure how to define this relationship in objecitfy4. I followed the tutorial http://www.eteration.com/objectify-an-easy-way-to-use-google-datastore/
Thanks.
Look at the Javadocs for Key. Instead of a public constructor, there is a more convenient creator method which requires less typing of <> generics:
Key<Course> courseKey = Key.create(Course.class, course.getId());
There are two keys that you might use:
first the GAE low-level com.google.appengine.api.datastore.Key and
second, the objectify's com.googlecode.objectify.Key.
You can use both with Objectify (as under the hood they are ultimately converted to low-level API).
Neither has a public constructor so you can not use new with them.
With low-level keys you'd use KeyFactory.createKey("Course", course.getId()).
With objectify key you'd use com.googlecode.objectify.Key.create(Course.class, course.getId())
When we use Objectify , if we need any Key to be created for condition(KeyFactory.createKey("Course", course.getId()) , In course object, Id field should be specified with index. It will work fine.

Idiomatic List Wrapper

In Google App Engine, I make lists of referenced properties much like this:
class Referenced(BaseModel):
name = db.StringProperty()
class Thing(BaseModel):
foo_keys = db.ListProperty(db.Key)
def __getattr__(self, attrname):
if attrname == 'foos':
return Referenced.get(self.foo_keys)
else:
return BaseModel.__getattr__(self, attrname)
This way, someone can have a Thing and say thing.foos and get something legitimate out of it. The problem comes when somebody says thing.foos.append(x). This will not save the added property because the underlying list of keys remains unchanged. So I quickly wrote this solution to make it easy to append keys to a list:
class KeyBackedList(list):
def __init__(self, key_class, key_list):
list.__init__(self, key_class.get(key_list))
self.key_class = key_class
self.key_list = key_list
def append(self, value):
self.key_list.append(value.key())
list.append(self, value)
class Thing(BaseModel):
foo_keys = db.ListProperty(db.Key)
def __getattr__(self, attrname):
if attrname == 'foos':
return KeyBackedList(Thing, self.foo_keys)
else:
return BaseModel.__getattr__(self, attrname)
This is great for proof-of-concept, in that it works exactly as expected when calling append. However, I would never give this to other people, since they might mutate the list in other ways (thing[1:9] = whatevs or thing.sort()). Sure, I could go define all the __setslice__ and whatnot, but that seems to leave me open for obnoxious bugs. However, that is the best solution I can come up with.
Is there a better way to do what I am trying to do (something in the Python library perhaps)? Or am I going about this the wrong way and trying to make things too smooth?
If you want to modify things like this, you shouldn't be changing __getattr__ on the model; instead, you should write a custom Property class.
As you've observed, though, creating a workable 'ReferenceListProperty' is difficult and involved, and there are many subtle edge cases. I would recommend sticking with the list of keys, and fetching the referenced entities in your code when needed.

Using Linq to filter parents by their children

Having some problems with my Silverlight app (with RIA services) filtering my results. The idea is on the client I set up the EntityQuery and its filters and call load. However this isn't working for me.
Heres my code.
public void FireQuery(string filterValue)
{
EntityQuery<Parent> query = m_ParentDomainContext.GetParentQuery();
query = query.Where(p => p.Children.Any(c => c.Name.Contains(filterValue)));
m_ParentDomainContext.Load(query, Query_Completed, null);
}
Compiles just fine, however, runtime I get "Query operator 'Any' is not supported." Exception.
Does anyone know of a good way to filter like this? Again, I'm looking for a way to set this up on the client.
EDIT: I should note, I've tried a few other queries as well, with similar results:
query = query.Where(p => p.Children.Where(c => c.Name.Contains(filterValue)).Count() != 0);
query = query.Where(p => p.Children.Where(c => c.Name.Contains(filterValue)).FirstOrDefault != null);
query = query.Where(p => p.Children.Where(c => c.Name.Contains(filterValue)).Any());
Query Operator 'Count/FirstOrDefault/Any' is not supported. I'm clearly missing something here...
As I tried to play around a little with this, I figured out that methods like First, Any and Count can't be used with LINQ to Entities (and, I believe, even NHibernate) over WCF RIA Services because they're not defined on the IQueryable itself, but, instread, are extention methods defined in the System.Linqnamespace. That is precisely why this shows as a run-time exception and not a compile-time error. The only extension methods that can be used here are those found in System.ServiceModel.DomainServices.Client (such as Where, Skip, Take, OrderBy, etc.).
This has to do with the "EntityQuery" objects, because those need to be composed and sent back to the server, whereas for the collections (such as m_ParentDomainContext.Parents in your case), you can use the System.Linq extension methods freely.
In order to implement this functionality, I suggest, as Thomas Levesque said, to expose it from the server in order to only get the data you want, or, alternatively, you can compose a query using the available constructs (the ones in System.ServiceModel.DomainServices.Client) and then apply the other filters on the resulting data (where you can use extension methods from the System.Linq namespace).
PS: I tried this with both classic Entity Framework and Entity Framework CodeFirst, and had the same results.
I hope this helps

Resources