Lorenzo
Lorenzo

Reputation: 29427

T4 relationship generation

suppose I have the following tables and relations:

CREATE TABLE [dbo].[Customers] (
    [CustomerID] [int] IDENTITY(1,1) NOT NULL,
    [Description] [nvarchar](255) NOT NULL
 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED ([CustomerID] ASC) 

CREATE TABLE [dbo].[Orders](
    [OrderID] [int] IDENTITY(1,1) NOT NULL,
    [CustomerID] [int] NOT NULL,
        ...
 CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ([OrderID] ASC)

ALTER TABLE [dbo].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Customers] 
    FOREIGN KEY([CustomerID]) REFERENCES [dbo].[Customers] ([CustomerID])

I am using some T4 templates to generate simple POCO classes with a property for each database column. This is very easy and really funny. In fact, the code I have is able to generate a single class for each table like in the following sample

public class Customer {
    public int CustomerID { get; set; }
    public string Description { get; set; }
}

I would like now to also create code that maps relationship between tables (1-N, 1-1) so to obtain, for example a class like this one

public class Customer {
    public int CustomerID { get; set; }
    public string Description { get; set; }
    public IList<Order> Orders { get; set; }
}

Unfortunately my code does not work. Here it is:

foreach ( NavigationProperty navProperty in entity.NavigationProperties.Where( p => p.DeclaringType == entity ) ) {
    string elementType = ((EntityType)( (RefType)navProperty.ToEndMember.TypeUsage.EdmType ).ElementType).Name;
    string relationshipName = navProperty.ToEndMember.DeclaringType.FullName;
    string targetRoleName = navProperty.ToEndMember.Name;
    if ( navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ) {
        <#=Accessibility.ForProperty( navProperty ) #> IList<<#=navProperty.Name#>> <#=navProperty.Name#> { get; set; }
    }
}

Unfortunately this generate code like this one:

public class Customer {
    public int CustomerID { get; set; }
    public string Description { get; set; }
    public IList<Orders> Orders { get; set; }   // NOTE THE PLURAL IN THE TYPE NAME!!!
}

which is the entity set name not the entity name. What I have to do to solve this problem?

NOTE: I am using EF for the .NET 3.5 version. Also I am including the EF.Utility.CS.ttinclude available in Visual Studio 10.

Upvotes: 0

Views: 1008

Answers (2)

Lorenzo
Lorenzo

Reputation: 29427

Found the solution. This is the correct code:

foreach ( NavigationProperty navProperty in entity.NavigationProperties.Where( p => p.DeclaringType == entity ) ) {
    string elementType = ((EntityType)( (RefType)navProperty.ToEndMember.TypeUsage.EdmType ).ElementType).Name;
    if ( navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ) {
        <#=Accessibility.ForProperty( navProperty ) #> IList<<#= elementType #>> <#=navProperty.Name#> { get; set; }
    }
}

Upvotes: 1

bwbrowning
bwbrowning

Reputation: 6520

Instead of using

navProperty.name

inside of your list declaration

Can you use

navProperty.ToEndMember

Through that property I think you should be able to find the real non-pluralized class name

Upvotes: 0

Related Questions