Entity Framework 5 how to specify a criteria on navigation property - entity-framework-5

in C# Entity Framework 5 I have
class Order {
// ....
public bool IsArchived {get; set;}
}
class Customer {
[ForeignKey("CustomerId")]
public /*virtual*/ IList<Order> Orders {get; set;}
}
all is fine the Orders per customer load up nicely. But I just want the orders where IsArchived is false, due to there are too many old orders I do not require. Is there any way to eager load only the non archived orders. Is this possible? Thank you.

Related

CRUD and Query with ServiceStack - Need to get rid of some confusion

I am a bit confused with ServiceStack 'old' and 'new' API and need some clarification and best practices, especially with Request / Response DTO's and routing. I watched some courses on Pluralsight and have the first three books listet on servicestack.net in my electronic bookshelf.
I like to 'restify' an existing application which is built using DDD patterns which means I have a high level of abstraction. The client is WPF and follows the MVVM pattern. I have 'client side service', 'server side service' and repository classes (and some aggregates too). I use NHibernate 4 (with fluent API and a code-first approach) as ORM. Only my repository classes know about the ORM. I have DTO's for all my Entity objects and in my WPF client I only work with those DTOs in the ViewModel classes. I heavily use AutoMapper to 'transfer' Entity objects to my DTO's and vice versa.
My confusion starts exactly with these DTO's and the Request / Response DTOs used in ServiceStack. Here is a very much simplified example of an Address Entity which illustrates the problem:
All my Entity Objects derive from EntityBase which contains basic properties used in all Entities:
public abstract class EntityBase : IEntity
{
public virtual Guid Id { get; protected set; }
public virtual DateTime CDate { get; set; } //creation date
public virtual string CUser { get; set; } //creation user
public virtual DateTime MDate { get; set; } //last modification date
public virtual string MUser { get; set; } //last modification user
//
// some operators and helper methods irrelevant for the question
// ....
}
public class Address : EntityBase
{
public string Street { get; private set; }
public string AdrInfo1 { get; private set; }
public string AdrInfo2 { get; private set; }
public string ZipCode { get; private set; }
public string City { get; private set; }
public string Country { get; private set; }
}
Of course there are collections and references to related objects which are ignored here as well as database mappers, naming conventions etc. The DTO I have looks like this:
public class AddressDto
{
public Guid Id { get; set; } // NHibernate GUID.comb, NO autoincrement ints!!
public DateTime CDate { get; set; }
public string CUser { get; set; }
public DateTime MDate { get; set; }
public string MUser { get; set; }
public string Street { get; private set; }
public string AdrInfo1 { get; private set; }
public string AdrInfo2 { get; private set; }
public string ZipCode { get; private set; }
public string City { get; private set; }
public string Country { get; private set; }
}
To use this with ServiceStack I need to support the following:
CRUD functionality
Filter / search functionality
So my 'Address service' should have the following methods:
GetAddresses (ALL, ById, ByZip, ByCountry, ByCity)
AddAddress (Complete AddressDTO without Id. CDate, CUser are filled automatically without user input)
UpdateAddress (Complete AddressDTO without CUser and CDate, MDate and MUser filled automatically without user input)
DeleteAddress (Just the Id)
For me it is pretty clear, that all Requests return either a single AddressDto or a List<AddressDto> as ResponseDTO except for the delete which should just return a status object.
But how to define all those RequestDTO's? Do I really have to define one DTO for EACH scenario?? In the books I only saw samples like:
[Route("/addresses", "GET")]
public class GetAddresses : IReturn<AddressesResponse> { }
[Route("/addresses/{Id}", "GET")]
public class GetAddressById : IReturn<AddressResponse>
{
public Guid Id { get; set; }
}
[Route("/addresses/{City}", "GET")]
public class GetAddressByCity : IReturn<AddressResponse>
{
public string City { get; set; }
}
// .... etc.
This is a lot of boilerplate code and remembers me a lot of old IDL compilers I used in C++ and CORBA.....
Especially for Create and Update I should be able to 'share' one DTO or even better reuse my existing DTO... For delete there is probably not much choice....
And then the filters. I have other DTOs with a lot more properties. A function approach like used in WCF, RPC etc is hell to code...
In my repositories I pass an entire DTO and use a predicate builder class which composes the LINQ where clause depending on the properties filled. This looks something like this:
List<AddressDto> addresses;
Expression<Func<Address, bool>> filter = PredicateBuilder.True<Address>();
if (!string.IsNullOrEmpty(address.Zip))
filter = filter.And(s => s.Zip == address.Zip);
// .... etc check all properties and dynamically build the filter
addresses = NhSession.Query<Address>()
.Where(filter)
.Select(a => new AddressDto
{
Id = a.Id,
CDate = a.CDate,
//.... etc
}).ToList();
Is there anything similar I could do with my RequestDTO and how should the routing be defined?
A lot of questions raised here have been covered in existing linked answers below. The Request / Response DTOs are what you use to define your Service Contract, i.e. instead of using RPC method signatures, you define your contract with messages that your Service accepts (Request DTO) and returns (Response DTO). This previous example also walks through guidelines on designing HTTP APIs with ServicesStack.
Use of well-defined DTOs have a very important role in Services:
You want to ensure all types your Services return are in DTOs since this, along with the base url of where your Services are hosted is all that's required for your Service Consumers to know in order to consume your Services. Which they can use with any of the .NET Service Clients to get an end-to-end Typed API without code-gen, tooling or any other artificial machinery.
DTOs are what defines your Services contract, keeping them isolated from any Server implementation is how your Service is able to encapsulate its capabilities (which can be of unbounded complexity) and make them available behind a remote facade. It separates what your Service provides from the complexity in how it realizes it. It defines the API for your Service and tells Service Consumers the minimum info they need to know to discover what functionality your Services provide and how to consume them (maintaining a similar role to Header files in C/C++ source code). Well-defined Service contracts decoupled from implementation, enforces interoperability ensuring that your Services don't mandate specific client implementations, ensuring they can be consumed by any HTTP Client on any platform. DTOs also define the shape and structure of your Services wire-format, ensuring they can be cleanly deserialized into native data structures, eliminating the effort in manually parsing Service Responses.
Auto Queryable Services
If you're doing a lot of data driven Services I recommend taking a look at AutoQuery which lets you define fully queryable Services without an implementation using just your Services Request DTO definition.

EF6 and MVC5: Using two fields as a combined key

I have several objects (Product, Rule, PriceDetail, etc.) that manage and store information in a CRUD application. I want a way to keep a log of when the data is updated, and to that end I've created an Update class, referenced as ICollection<Update> Updates within each data class.
When the tables are all generated, EF creates a FK for each class in the Updates table (Product_ID, Rule_ID, etc.). This seems horribly inefficient. Could I use a two-field key, such as enum ObjectType and long ID? Alternately, can I use string ID and force a pattern where the first N characters of the string identify the referencing object? If the latter, can the database auto-increment the string value?
Here's some example code, trimmed for placement here:
public class Update
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ID { get; set; }
public string Reason { get; set; }
public DateTime TimeOfUpdate { get; set; }
public long Product_ID { get; set; }
public long Rule_ID { get; set; }
}
public class Product
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ID { get; set; }
public string Name { get; set; }
public PriceDetail Price { get; set; }
public ICollection<Update> Updates { get; set; }
}
public class Rule
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long ID { get; set; }
public string Name { get; set; }
public ICollection<Condition> Conditions { get; set; }
public ICollection<Update> Updates { get; set; }
}
There are multiple ways of handling auditing logic.
Do you anticipate storing update history for every table? If it's going to be limited to a few tables, your design might work fine. If however, you want to update many tables, you might want to try out the options below.
Include 3 tables (Products, Updates and ProductUpdates). The Products tables will always have the latest data. The Updates tables will get a new row capturing the updated timestamp every time an entry in Products is updated. The ProductUpdates will have a foreign key to the Updates table and will have the old row from the Products table. This way you know exactly what the row looked at any point of time. Extending it to any other table X will require adding XUpdates table. But you wouldn't have the unnecessary 50 foreign keys that you mentioned.
Another option would be to have IsActive, UpdatedBy, UpdatedTimestamp, etc... columns in the tables that will be updated. Every time, you update a row, you mark it as inactive and insert a new row with the latest data. You can store the reason and rule columns also if needed.
You can also redesign your entities in such a way that their primary key is a foreign key to your updates table. This way you will eliminate the inelegance of all previous solutions. Every time you update, you will insert a row in the Updates table and use the generated Id as the primary key of a new row in your products table.
Entity Framework can help you in automating the process laid out in points 3 and 4. The basic idea would be to intercept the Save requests for updates and force an update and insert instead.
Lastly, you might also be able to use CLR triggers to have the audit functionality you want.
Each solution has its pros and cons. The best solution for you would depend upon your specific use case.

Deleting entity when a referenced entity is deleted

Using DDD, I have 4 aggregate roots where, using the appointment analogy, a clinic can have a number of patients, each patient can have a number of appointments, each appointment can have a number of prescriptions.
Now, to avoid creating a very big bloated Aggregate, Clinic in this case, I have created 4 separate aggregate roots.
public class Clinic
{
public Guid Id { get; private set; }
}
public class Patient
{
public Guid Id { get; private set; }
public Guid ClinicId { get; private set; }
public Patient(Guid clinicId)
{
ClinicId = clinicId;
}
}
public class Appointment
{
public Guid Id { get; private set; }
public Guid PatientId { get; private set; }
public Appointment(Guid patientId)
{
PatientId = patientId;
}
}
Now, the question is how should I manage the scenario where a patient is deleted, in which case all appointments referencing this patient should be deleted too.
I guess this is where a domain expert is going to come in handy. From a technical point of view it probably is going to depend on the architecture you decide on.
100% consistency
Here you could use an application service to first delete the patient and then all the appointments linked to that patient.
Eventual consistency
Using messaging you could publish PatientDeletedEvent that would be responded to by some endpoint that would delete the appointments.
However
You probably do not want to be deleting patients in the first place. Even so, your questions about the appointments for, say, setting a patient Inactive may still results in you wanting to delete future appointments.
This is where you would need a domain expert to guide you in creating the correct model and behaviour.

Entity Framework Linking tables

I’m using Entity Framework 5.0,
Scenario
"Organisation" has a list of "clients" and a list of "Periods" and a "CurrentPeriodID" At the start of each period some or all of the "Clients" are associated with that "Period", this I have done using a link table and this works OK so when I do "Organisation->Period->Clients" I get a list of "Clients" for the "Period".
Next I need to add some objects ("Activities") to the "Clients" for a "Period" so I get "Organisation->Period->Client->Activates" this won’t be the only one there will eventually be several other navigation properties that will need to be added to the "Clients" and the "Activities" and all of them have to be "Period" related, I also will have to be able to do (if possible) "Organisation->Period-Activities".
Question
What would be the best way of implementing the "Activities" for the "Organisation->Period-Client", I Don’t mind what way it is done Code First reverse Engineering etc. Also on the creation of the "Organisation" object could I load a current "Period" object using the "CurrentPeriodID" value which is stored in the "Organisation" object.
Thanks
To me this sounds like you need an additional entity that connects Period, Client and Activity, let's call it ClientActivityInPeriod. This entity - and the corresponding table - would have three foreign keys and three references (and no collections). I would make the primary key of that entity a composition of the three foreign keys because that combination must be unique, I guess. It would look like this (in Code-First style):
public class ClientActivityInPeriod
{
[Key, ForeignKey("Period"), Column(Order = 1)]
public int PeriodId { get; set; }
[Key, ForeignKey("Client"), Column(Order = 2)]
public int ClientId { get; set; }
[Key, ForeignKey("Activity"), Column(Order = 3)]
public int ActivityId { get; set; }
public Period Period { get; set; }
public Client Client { get; set; }
public Activity Activity { get; set; }
}
All three foreign keys are required (because the properties are not nullable).
Period, Client and Activity can have collections refering to this entity (but they don't need to), for example in Period:
public class Period
{
[Key]
public int PeriodId { get; set; }
public ICollection<ClientActivityInPeriod> ClientActivities { get; set; }
}
You can't have navigation properties like a collection of Clients in Period that would contain all clients that have any activities in the given period because it would require to have a foreign key from Client to Period or a many-to-many link table between Client and Period. Foreign key or link table would only be populated if the client has activities in that Period. Neither EF nor database is going to help you with such a business logic. You had to program this and ensure that the relationship is updated correctly if activities are added or removed from the period - which is error prone and a risk for your data consistency.
Instead you would fetch the clients that have activities in a given period 1 by a query, not by a navigation property, for example with:
var clientsWithActivitiesInPeriod1 = context.Periods
.Where(p => p.PeriodId == 1)
.SelectMany(p => p.ClientActivities.Select(ca => ca.Client))
.Distinct()
.ToList();

Where to create MySql tables ServiceStack & OrmLite

I am just wondering about when and where tables should be created for a persisted application. I have registered my database connection factory in Global.asax.cs:
container.Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(conn, MySqlDialectProvider.Instance));
I also understand that I need to use the OrmLite API to create tables from the classes I have defined. So for example to create my User class:
public class User
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
[Index(Unique = true)]
public string Email { get; set; }
public string Country { get; set; }
public string passwordHash { get; set; }
public DateTime Dob { get; set; }
public Sex Sex { get; set; }
public DateTime CreatedOn { get; set; }
public Active Active { get; set; }
}
I would execute the following:
Db.CreateTable<User>(false);
I have a lot of tables that need to be created. Should I create a separate class that first created all my tables like this or execute that in each rest call to UserService.
Also is it possible to create all my tables directly in my database, naming each table with its corresponding class, and then Orm would match classes to existing tables automatically?
Sorry this has me a bit confused. Thanks for any help you can give me.
I would create them in the AppHost.Configure() which is only run by a single main thread on Startup that's guaranteed to complete before any requests are served.
If you wanted to you can automate this somewhat by using reflection to find all the types that need to be created and calling the non-generic API versions:
db.CreateTable(overwrite:false, typeof(Table1));
db.CreateTable(overwrite:false, new[] { typeof(Table1), typeof(Table2, etc });
is it possible to create all my tables directly in my database, naming each table with its corresponding class, and then Orm would match classes to existing tables automatically?
You don't have to use OrmLite to create tables. If the table(s) already exist in your MySQL database (or you want to create using MySQL interface) you will be able to access them as long as the class name is the same as the table name. If table names don't match the class names, use the Alias attribute
[Alias("Users")] //If table name is Users
public class User
{
public int Id {get;set;}
}
I wouldn't create the tables in your services. Generally, I would do it in AppHost.Configure method which is run when the application starts. Doing this will attempt to create the tables every time your application is started (which could be once a day - see here) so you might want to set a flag in a config file to do a check for creating the tables.

Resources