Error querying DTO navigation properties with "any" - vb.net

In my BreezeController I have a method that returns a DTO with two properties. One property is a navigation property to one of my entities, and the other a boolean:
Public Function ProjectList() As IQueryable
Return From p In _contextProvider.Context.Projects
Where Not p.IsDeleted
Select New ProjectListItem() With {
.Project = p,
.HasTasks = (From t In _contextProvider.Context.ProjectTasks Where t.ProjectID = p.ID).Any()
}
End Function
Public Class ProjectListItem
Public Property Project As Project
Public Property HasTasks As Boolean
End Class
Simple queries against this method work fine, but my Project class has a collection of project managers, and using an "any" query against this collection is failing in the Breeze client code, before sending the query to the server, with the following error message:
Exception was thrown at line 10698, column 13 in http://localhost:2780/myapp/Scripts/breeze.debug.js
0x800a138f - JavaScript runtime error: Unable to get property 'isAnonymous' of undefined or null reference
This is in the proto._validate method of FnNode, where entityType is null.
My query (I'm trying to find all projects for a specific project manager) is built up in pieces, but the relevant parts are:
var p = breeze.Predicate.create("ProjectManagerID", op.Equals, id);
var predicate = breeze.Predicate.create("Project.ProjectManagers", "any", p);
// code common to all queries...
var query = breeze.EntityQuery.from("ProjectList");
query = query.where(predicate);
query = query.select("Project.Prop1,Project.Prop2,Project.etc,HasTasks");
return query.using(this.manager).execute();
I create other predicates and run them through the same common logic and they work fine, so it seems to be limited to "any" queries, e.g. this one works...
predicate = breeze.Predicate.create("Project.ClientNumber", op.Contains, search)
.or("Project.ClientName", op.Contains, search)
.or("Project.Notes", op.Contains, search);
I am still using Breeze 1.4.16 (WebAPI v1, .NET 4.0), but have tried updating the Breeze.Client package to 1.5.1, which makes no difference.
Any ideas what I'm doing wrong?
If I manually build the OData query I am looking for, then I get the results that I want, e.g.
http://localhost:1234/myApp/breeze/myController/ProjectList?$filter=Project/ProjectManagers/any(p:p/ProjectManagerID eq 234)&$select=Project/Prop1,Project/Prop2,HasTasks

Related

RepoDb cannot find mapping configuration

I'm trying to use RepoDb to query the contents of a table (in an existing Sql Server database), but all my attempts result in an InvalidOperationException (There are no 'contructor parameter' and/or 'property member' bindings found between the resultset of the data reader and the type 'MyType').
The query I'm using looks like the following:
public Task<ICollection<MyType>> GetAllAsync()
{
var result = new List<MyType>();
using (var db = new SqlConnection(connectionString).EnsureOpen())
{
result = (await db.ExecuteQueryAsync<MyType>("select * from mytype")).ToList();
}
return result;
}
I'm trying to run this via a unit test, similar to the following:
[Test]
public async Task MyTypeFetcher_returns_all()
{
SqlServerBootstrap.Initialize();
var sut = new MyTypeFetcher("connection string");
var actual = await sut.GetAllAsync();
Assert.IsNotNull(actual);
}
The Entity I'm trying to map to matches the database table (i.e. class name and table name are the same, property names and table column names also match).
I've also tried:
putting annotations on the class I am trying to map to (both at the class level and the property level)
using the ClassMapper to map the class to the db table
using the FluentMapper to map the entire class (i.e. entity-table, all columns, identity, primary)
putting all mappings into a static class which holds all mapping and configuration and calling that in the test
providing mapping information directly in the test via both ClassMapper and FluentMapper
From the error message it seems like RepoDb cannot find the mappings I'm providing. Unfortunately I have no idea how to go about fixing this. I've been through the documentation and the sample tutorials, but I haven't been able to find anything of use. Most of them don't seem to need any mapping configuration (similar to what you would expect when using Dapper). What am I missing, and how can I fix this?

How to get the value of an MSBuild variable

How can I get the value of MSBuild variable (ex. $(MSBuildToolsPath), $(MSBuildAssemblyVersion), $(TargetFrameworkIdentifier), etc.).
I need to get the value on the C# side, but I can access msbuild.exe if it's not available from the C# code.
BuildManager and the likes are for building, only; Microsoft decided to split up the MSBuild API in different namespaces according to functionality. Once you know that it's not too hard figuring out what you need: you just need to evaluate properties, so the Project class from the Evaluation namespace seems like the proper choice. It has a Properties member exposing all properties:
var project = new Microsoft.Build.Evaluation.Project( #"my.vcxproj" );
foreach( var property in p.Properties )
{
System.Console.WriteLine( "{0} = {1}",
property.Name, property.EvaluatedValue );
}

NHibernate (Fluent mapping) ReferencesAny<object>

Base entity interface is IEntity which requires only "object ID {get;set;}" to be implemented.
Now, in almost every case ID is of Guid type (except for membership etc).
I am using following code to do mapping of interface
...
AnyPart<IEntity> primaryMap = ReferencesAny(x => x.Primary)
.IdentityType<object>() // tried with .IdentityType<Guid>()
.EntityIdentifierColumn("PrimaryID")
.EntityTypeColumn("PrimaryType")
.MetaType<string>();
...
Of course, next I am adding meta values.
So, Now getting error
Source array was not long enough. Check srcIndex and length, and the array's lower bound
And with .IdentityType<Guid>()
could not resolve property: Primary.ID of: Founder.Connection [.SingleOrDefault[Founder.Connection](NHibernate.Linq.NhQueryable`1[Founder.Connection], Quote((x, ) => (OrElse(AndAlso(Equal(x.Primary.ID, 35c2142a-4c17-4b77-96fd-a2570028a211), Equal(x.Secondary.ID, 35c2142a-4c17-4b77-96fd-a2570028a211)), AndAlso(Equal(x.Secondary.ID, 35c2142a-4c17-4b77-96fd-a2570028a211), Equal(x.Primary.ID, 35c2142a-4c17-4b77-96fd-a2570028a211))))), )]
UPDATE:
I tried also with .IdentityType(x=>x.ID) but same problem (Source array was not long enough)
UPDATE II:
Query (Actually whole method containing query) that this error occurs on is bellow:
public IQueryable<Connection> GetConnections(IEntity connectable)
{
IQueryable<Connection> query =
Query().Where(
x => x.Primary.ID == connectable.ID || x.Secondary.ID == connectable.ID);
return query;
}
Try this in the query: x.Primary == connectable (without ID).
The problem is that you reference an object (or another unmapped type, that's why you need an any mapping). There is no ID on object.
By the way, using HQL would allow you to access the id by using the keyword id, which is not available in Linq (technically it could be made available as extension method, but I don't know Linq to NH good enough to say if it had been implemented). Every any reference conceptually has an id and a class.

fetch single property in object from database

I am working on NET MVC 3.0 and Nhibernate 3.0. I want to fetch only one property from database to an object.
For instance, suppose I have a class Module. I want to select all the names from module table (like select modulename from module query) and an prepare a list of module objects which have only name. All other properties can be null.
I tried this using QueryOver API:
IQueryOver<ProjectModule> module = session.QueryOver<ProjectModule>()
.Select(a=>a.Name)
.TransformUsing(
NHibernate.Transform.Transformers.AliasToBean<ProjectModule>());
pm = module.List<ProjectModule>();
pm is IList<ProjectModule> type.
Transaction gets committed successfully. No error occurred, but I get a list of module objects with all properties = null. Module name null, module id null etc.
I checked what query is executing on SQL using NUnit and got this: SELECT this_Name as y0_ FROM ProjectModule this_.
To be more accurate create a DTO object, assume ProjectModuleDto, that will contain only the Name. It's not a good practice to use the the domain object with uninitialized values through your code, cause it creates confusions of filled data in various scenarious.
And the fllowing code will do the trick - populate the list of DTOs: ProjectModuleDto with correct Name of project module from database:
ProjectModuleDto projectModuleDto = null;
IQueryOver<ProjectModule> module = session.QueryOver<ProjectModule>()
.SelectList(
list=>list.Select(a => a.Name).WithAlias(() => projectModuleDto.Name)
)
TransformUsing(NHibernate.Transform.Transformers.AliasToBean<ProjectModuleDto>());
pm = module.List<ProjectModuleDto>();
If you are fetching only a single property, you don't need to use transformers. Try to use a List<string> directly:
var moduleNames = session.QueryOver<ProjectModule>()
.Select(a => a.Name)
.List<string>();
Read more about QueryOver syntax on NHibernate blog.
Is this what you're looking for?
List<ProjectModule> result = new List<ProjectModule>();
session.QueryOver<ProjectModule>()
.Select(a => a.Name)
.ToList().ForEach(delegate(string mName)
{
result.Add(ProjectModule() { Name = mName });
});

Retrieving data from WCF service

Let's say I have database with two tables - Groups and Items.
Table Groups has only two columns: Id and Name.
Table Items has three columns: Id, GroupId and Name.
As you can see, there is one-to-many relation between Groups and Items.
I'm trying to build a web service using WCF and LINQ. I've added new LINQ to SQL classes file, and I've imported these two tables. Visual Studio has automatically generated proper classes for me.
After that, I've create simple client for the service, just to check if everything is working. After I call GetAllGroups() method, I get all groups from Groups table. But their property Items is always null.
So my question is - is there a way to force WCF to return whole class (whole Group class and all Items that belong to it)? Or is this the way it should behave?
EDIT: This is function inside WCF Service that returns all Groups:
public List<Group> GetAllGroups()
{
List<Group> groups = (from r in db.Groups select r).ToList();
return groups;
}
I've checked while debugging and every Group object inside GetAllGroups() function has it's items, but after client receives them - every Items property is set to null.
Most likely, you're experiencing the default "lazy-loading" behavior of Linq-to-SQL. When you debug and look at the .Items collection - that causes the items to be loaded. This doesn't happen however when your service code runs normally.
You can however enforce "eager-loading" of those items - try something like this:
(see Using DataLoadOptions to Control Deferred Loading or LINQ to SQL, Lazy Loading and Prefetching for more details)
public List<Group> GetAllGroups()
{
// this line should really be where you *instantiate* your "db" context!
db.DeferredLoadingEnabled = false;
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Group>(g => g.Items);
db.LoadOptions = dlo;
List<Group> groups = (from r in db.Groups select r).ToList();
return groups;
}
Do you get the Items collection populated now, when you call your service?