Entity Framework: Many-to-Many - entity-framework

I have the following scenario: A Doctor can have multiple Companions. A Companion can also have multiple Doctors. Here are my classses (minus the context):
Public Class Doctor
Public Property DoctorId As Integer
Public Property Regeration As Integer
Public Property Name As String
Public Property Actor As String
Public Property Companions As List(Of Companion)
End Class
Public Class Companion
Public Property CompanionId As Integer
Public Property Name As String
Public Property Actor As String
Public Property Doctors As List(Of Doctor)
End Class
Public Class DoctorViewModel
Public Property DoctorId As Integer
Public Property Actor As String
Public Property Companions As List(Of CompanionViewModel)
End Class
Public Class CompanionViewModel
Public Property Actor As String
End Class
I'm trying to fetch a singular Doctor with a list of companions who have travelled with him. This I can do quite simply, but I'm trying to shape the query to get only a few columns and not the entire entity. He is my bungled query - the X's are what I can't figure out.
Dim query = From d In context.Doctors
From c In context.Companions
Select New DoctorViewModel With {
.Actor = d.Actor,
.DoctorId = d.DoctorId,
.Companions = XXXXXXX}
EDIT: If I query:
(From d In Tardis.Doctors
Where d.Actor = "Tom Baker"
Select New DoctorViewModel With {.Actor = d.Actor, .Companions = d.Companions.Select(Function(c) New CompanionViewModel With {.Actor = c.Actor})}).SingleOrDefault
I get:
"Unable to cast the type 'System.Collections.Generic.IEnumerable1' to
type 'System.Collections.Generic.List1'. LINQ to Entities only
supports casting Entity Data Model primitive types."
Would it be considered nasty to ditch the ViewModel classes in the query and just get the stuff as an anonymous type, then pass this to a constuctor in a ViewModel (my models have a whack of functions that are needed) and fill the class like this?

It probably would be not only okay but much more readable (aka maintainable) as well. Especially since the query wouldn't return an anonymous type, it would return an IQueryable

Solved! I've spent days on this! Trick was to change the List inside the Doctor ViewModel to IEnumerable(Of CompanionViewModel)

Related

How to query using fields of subclasses for Spring data repository

Here is my entity class:
public class User {
#Id
UserIdentifier userIdentifier;
String name;
}
public class UserIdentifier {
String ssn;
String id;
}
Here is what I am trying to do:
public interface UserRepository extends MongoRepository<User, UserIdentifier>
{
User findBySsn(String ssn);
}
I get an exception message (runtime) saying:
No property ssn found on User!
How can I implement/declare such a query?
According to Spring Data Repositories reference:
Property expressions can refer only to a direct property of the managed entity, as shown in the preceding example. At query creation time you already make sure that the parsed property is a property of the managed domain class. However, you can also define constraints by traversing nested properties.
So, instead of
User findBySsn(String ssn);
the following worked (in my example):
User findByUserIdentifierSsn(String ssn);

Null pointer when using QueryDSL subtypes

I am trying to create a subtype query along the following lines, but tyre is coming back as null even if I set #QueryInit("tyre") on the wheel property of car.
QWheel wheel = QCar.car.wheel;
QTyre tyre = wheel.as(QRoadWheel.class).tyre;
BooleanExpression tyreFittedOverYearAgo
= tyre.fitted.lt(today.minusYears(1));
Iterable<Car> carsWithOldTyres = repo.findAll(tyreFittedOverYearAgo);
How do I get QueryDSL to initialise tyre when it is accessed using as()?
By default Querydsl initializes only direct reference properties. In cases where longer initialization paths are required, these have to be annotated in the domain types via com.mysema.query.annotations.QueryInit usage. QueryInit is used on properties where deep initializations are needed.
#Entity
class Event {
#QueryInit("customer")
Account account;
}
#Entity
class Account{
Customer customer;
}
#Entity
class Customer{
String name;
String address;
}
This will intialize customer.name ,customer.address
I've not been able to establish why, but I've now got things working but by using:
#QueryInit("*")
Tyre tyre;

classic asp/vbscript class to track employees and performance metrics

I am trying to create a classic asp/vbscript class that will allow me to easily manage a small number of employees (30-40) along with some metrics associated with those employees, about 14 metrics each. I've done some tutorials online and can't quite get how I should proceed. What I have so far is below. It's not much, basically I think I can only add the employees to a dictionary in the class, but I don't know where to go from here.
class iagent
private di_agents
private ar_metrics
private pri_agent_counter
Public function add_agent(uuid)
di_agents.Add uuid, pri_agent_counter
pri_agent_counter=pri_agent_counter+1
end function
private sub Class_initialize
pri_agent_counter=1
dim ar_metrics(14, 5)
set di_agents = CreateObject("Scripting.Dictionary")
end sub
end class
The class you have is just a wrapper around a dictionary. Are you talking about creating a class that represents an employee?
Class Employee
Public Name
Public Age
Public Phone
'other properties
End Class
Then you can instantiate Employee like this and set your properties
Set e = New Employee
e.Name = "Some name"
You could then store your instances of Employee in a dictionary, perhaps paired with an ID:
Set d = CreateObject("Scripting.Dictionary")
Call d.Add(uuid, e)
However, you're better off using a database for this and using ASP/VBS to extract records... Unless this is just an exercise

DbSet.Find method ridiculously slow compared to .SingleOrDefault on ID

I have the following code (Database is SQL Server Compact 4.0):
Dim competitor=context.Competitors.Find(id)
When I profile this the Find method takes 300+ms to retrieve the competitor from a table of just 60 records.
When I change the code to:
Dim competitor=context.Competitors.SingleOrDefault(function(c) c.ID=id)
Then the competitor is found in just 3 ms.
The Competitor class:
Public Class Competitor
Implements IEquatable(Of Competitor)
Public Sub New()
CompetitionSubscriptions = New List(Of CompetitionSubscription)
OpponentMeetings = New List(Of Meeting)
GUID = GUID.NewGuid
End Sub
Public Sub New(name As String)
Me.New()
Me.Name = name
End Sub
'ID'
Public Property ID As Long
Public Property GUID As Guid
'NATIVE PROPERTIES'
Public Property Name As String
'NAVIGATION PROPERTIES'
Public Overridable Property CompetitionSubscriptions As ICollection(Of CompetitionSubscription)
Public Overridable Property OpponentMeetings As ICollection(Of Meeting)
End Class
I defined the many to many relations for CompetitionSubscriptions and OpponentMeetings using the fluent API.
The ID property of the Competitor class is a Long which is translated by Code First to an Identity column with a primary key in the datatable (SQL Server Compact 4.0)
What is going on here??
Find calls DetectChanges internally, SingleOrDefault (or generally any query) doesn't. DetectChanges is an expensive operation, so that's the reason why Find is slower (but it might become faster if the entity is already loaded into the context because Find would not run a query but just return the loaded entity).
If you want to use Find for a lot of entities - in a loop for example - you can disable automatic change detection like so (can't write it in VB, so a C# example):
try
{
context.Configuration.AutoDetectChangesEnabled = false;
foreach (var id in someIdCollection)
{
var competitor = context.Competitors.Find(id);
// ...
}
}
finally
{
context.Configuration.AutoDetectChangesEnabled = true;
}
Now, Find won't call DetectChanges with every call and it should be as fast as SingleOrDefault (and faster if the entity is already attached to the context).
Automatic change detection is a complex and somewhat mysterious subject. A great detailed discussion can be found in this four-part series:
(Link to part 1, the links to parts 2, 3 and 4 are at the beginning of that article)
http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/

Adding custom property to object returned from WCF RIA Services

I have a stored procedure in my Entity Framework Model. I've added a Function Import and mapped the results to a Complex Type.
I want to add an extra property to this Complex type, that I'll populate in my Domain Service, not coming back from the stored procedure. I added a myClass.shared.cs file and implemented added the property like so:
//myClass.shared.cs
public partial class myClass
{
public string myProperty {get;set;}
}
I populate this in my domain service when I return the object, e.g.:
public myClass GetMyClass(int myClassID)
{
myClass theClass= this.ObjectContext.StoredProc(myClassID).FirstOrDefault();
class.myProperty = 12345;
return theClass;
}
When I get the return values of this method on the client side theClass.myProperty is always null but all values from the stored procedure are populated, am I missing something?
I've tried decorating the myProperty with the [DataMember] attribute but this throws the error:
"The type 'myClass' already contains a
definition for 'myProperty'"
How can I get this to return the value set in the Domain Service to the client?
There was no need to put this in the shared.cs class. The shared.cs class copies the actual code over to the client side and is useful for adding methods etc. but to add a new property, all I had to do was add a partial class (NOT in myClass.shared.cs) and decorate it with DataMember.
public partial class myClass
{
[DataMember]
public string myProperty {get;set;}
}