Mapping two properties one to many to the same collection - c#-4.0

I'm using Entity Framework 4.3 code first. How do I create two "one to many"-relationships between two properties in class A and a collection in class B?
My model:
public class Shaft
{
public int Id { get; set; }
public virtual Coupling FirstEnd { get; set; }
public virtual Coupling SecondEnd { get; set; }
}
public class Coupling
{
public int Id { get; set; }
public virtual ICollection<Shaft> Shafts { get; set; }
}

Well, a one-to-many relationship is called one-to-many because there is one element on the first end of the relationship and many elements on the other end. You also can have a zero or one-to-many relationship which only means that the element on the not-many side can be null (or NULL in the database).
What you are trying to define is a two-to-many (or perhaps zero or one or two-to-many) relationship. Such a thing does not exist in a relational database nor does it exist in Entity Framework.
When you define a relationship with EF you always need pairs of two navigation properties in source and target class. It is possible to omit one of the navigation properties but that does not mean that you can move the end of this relationship to another navigation property that already belongs to another relationship.
In your specific case you have two relationships because your two navigation properties FirstEnd and SecondEnd in Shaft represent two different foreign keys. Therefore you either need two collections in Coupling or you can relate the existing property Coupling.Shafts to either FirstEnd or SecondEnd but not to both. The other reference would refer to an "invisible" not exposed navigation collection in Coupling. (This is what will happen with the mapping in your own answer: EF will take the second mapping block that overwrites the first one, create a relationship between SecondEnd and Shafts and then another relationship between FirstEnd and a not exposed relationship end in Coupling, not Shafts again.)
The solution with two collections - which makes more sense in my opinion - would look like this:
public class Coupling
{
public int Id { get; set; }
public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }
}
And this mapping:
modelBuilder.Entity<Coupling>()
.HasMany(x => x.ShaftsWithFirstEndHere)
.WithOptional(x => x.FirstEnd);
modelBuilder.Entity<Coupling>()
.HasMany(x => x.ShaftsWithSecondEndHere)
.WithOptional(x => x.SecondEnd);
You can create a readonly and not mapped helper property to concatenate the two collections togother to one collection, but this concatenation will happen in memory after the two navigation collections already have been loaded:
public class Coupling
{
public int Id { get; set; }
public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; }
public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; }
// not mapped to DB because it has only a getter = readonly
public IEnumerable<Shaft> Shafts
{
get { return ShaftsWithFirstEndHere.Concat(ShaftsWithSecondEndHere); }
}
}
There is no kind of mapping which would do such a concatenation automatically. Be aware that a navigation collection property in a one-to-many relationship is just the result of a query by a foreign key in the dependent table (= Shaft in your example). The foreign key which is used to populate a collection (by using Include for example or when lazy loading is triggered) is well defined by the relationship mapping and it is only one key - either the key for FirstEnd or the key for SecondEnd but not both. What you are trying to achieve is the combined concatenated result of two queries by two different foreign keys. And that's not possible with relationship mapping.

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.

categorize ServiceStack methods

Imagine I have two "areas" in my API, inventory and orders. I can quite easily group all methods related to inventory into "/inventory/" and to orders "/orders/" routes.
However, when I go to the root page of API where all methods are shown (IndexOperations.html) all methods are mixed together into one big list.
Is there any way to group methods from different areas on that list? For example show something like this on the operations index page.
Inventory
Method1
Method2
Orders
Method1
Method2
Group your operations:
If you group your DTOs into a static class as shown below, then ordering will be taken care of automatically assuming you want the groups alphabetically.
public static class UserOperations
{
[Route("/Users","POST")]
public class CreateUserRequest
{
public string Name { get; set; }
public int Age { get; set; }
}
...
}
public static class DuckOperations
{
[Route("/Ducks","POST")]
public class CreateDuckRequest
{
public string Name { get; set; }
public int Age { get; set; }
}
...
}
Alternatively specify the sort:
The ServiceStack MetadataFeature in v4.09+ provides access to the IndexPageFilter which lets you specify specify the Sort function that is applied to the index pages' OperationNames, where the OperationName is the full type name of the DTO.
var metadata = Plugins.First(x => x is MetadataFeature) as MetadataFeature;
// This is the default sort, replace with one that groups
metadata.IndexPageFilter = (page) => page.OperationNames.Sort((a,b) => b.CompareTo(a));
I hope this helps.

Orchard: how to persist a record without content

Allright, this should be fairly easy.
I would like to persist some records for my module in Orchard (1.7.2) without those records being also a ContentPartRecord.
In other words, I would like to be able to persist in DB the following objects:
public class LogItemRecord
{
public virtual string Message { get; set; }
}
..which is already mapped on to the db. But notice that this class is not derived from ContentPartRecord, as it is most certainly not one.
However, when I call IRepository instance's .Create method, all I get is a lousy nHibernate exception:
No persister for: MyModule.Models.LogItemRecord
...which disappears if I do declare the LogItem record as having been inherited from ContentPartRecord, but trying to persist that, apart from being hacky-tacky, runs into an exception of its own, where nHibernate again justly complains that the Id value for the record is zero, though in not so many words.
So... how do I play nicely with Orchard and use its API to persist objects of my own that are not ContentParts / ContentItems?
I'm running 1.7.3 (also tested in 1.7.2) and have successfully been able to persist the following class to the DB:
public class ContactRecord
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string JobTitle { get; set; }
public virtual string Email { get; set; }
public virtual string Phone { get; set; }
}
Here are the relevant lines from Migrations.cs
SchemaBuilder.CreateTable(
typeof(ContactRecord).Name,
table => table
.Column<int>("Id", col => col.Identity().PrimaryKey())
.Column<string>("Name")
.Column<string>("JobTitle")
.Column<string>("Email")
.Column<string>("Phone")
);
I'm going to assume that the code you've shown for LogItemRecord is the complete class definition when making the following statement...
I think that any Record class you store in the DB needs an Id property, and that property should be marked as Identity and PrimaryKey in the table definition (as I've done above).
When you create a *Record class which inherits from ContentPartRecord and setup the table like
SchemaBuilder.CreateTable(
"YourRecord",
table => table
.ContentPartRecord()
// more column definitions
);
then you get the Id property/PK "for free" by inheritance and calling .ContentPartRecord() in the Migration.
See the PersonRecord in the Orchard Training Demo Module for another example of storing a standard class as a record in the DB.

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();

EF - One to one relationship

I have the following class:
public class FinanceiroLancamento
{
/// <summary>Identificação</summary>
public override int Id { get; set; }
/// <summary>Financeiro caixa</summary>
public FinanceiroLancamentoCaixa FinanceiroLancamentoCaixa { get; set; }
}
public class FinanceiroLancamentoCaixa
{
/// <summary>Identificação</summary>
public override int Id { get; set; }
/// <summary>Identificação do lançamento financeiro</summary>
public int IdFinanceiroLancamento { get; set; }
}
When I try to map and execute migration it´s return:
Property name 'IdFinanceiroLancamento' was already defined.
To solve this problem I needed to comment idfinanceirolancamento and map like this:
HasRequired(e => e.FinanceiroLancamentoCaixa)
.WithRequiredPrincipal()
.Map(m => m.MapKey("IdFinanceiroLancamento"));
The question is:
How can I this FK (FinanceiroLancamento -> FinanceiroLancamentoCaixa) keeping the "IdFinanceiroLancamento { get; set; }"?
This is very important in my case to use later in the class.
Ps: FinanceiroLancamento does not need a FinanceiroLancamentoCaixa, but when FinanceiroLancamentoCaixa exists he needs a FinanceiroLancamento.
Best regards.
Wilton Ruffato Wonrath
Entity Framework requires that 1:1 mappings share the same primary key. In your case, you are trying to use a different member as the mapping id. Also, do not override the base class id, just inherit it.
What you want Is this:
.HasRequired(e => e.FinanceiroLancamentoCaixa)
.WithRequiredPrincipal();
Entity Framework does not allow you to use a 1:1 that is not a shared primary key, so you can't do it in EF. If you absolutely need this, you may have to do it as a stored procedure and call it from EF.
The reason you can't have a 1:1 like this is because the data model allows you to set IdFinanceiroLancamento to the same ID in more than one record, thus breaking your 1:1.
Basically, EF will not allow you to create models with mappings that allow for a violation of the mapping, even if you never create duplicates, it's still a possibility. EF doesn't know about unique constraints either so placing a unique constraint won't tell EF that it's ok.
If you'd like to see this feature, I suggest you vote for it at the EF uservoice:
http://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/1050579-unique-constraint-i-e-candidate-key-support

Resources