Генерация отношений T4

предположим, что у меня есть следующие таблицы и отношения:

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])

Я использую некоторые шаблоны T4 для создания простых классов POCO со свойством для каждого столбца базы данных. Это очень легко и очень смешно. Фактически, код, который у меня есть, может генерировать один класс для каждой таблицы, как в следующем примере.

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

Теперь я хотел бы также создать код, который отображает отношения между таблицами (1-N, 1-1), чтобы получить, например, такой класс, как этот.

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

К сожалению, мой код не работает. Вот:

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; }
    }
}

К сожалению, это генерирует код, подобный этому:

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!!!
}

которое является именем набора сущностей, а не именем сущности. Что я должен сделать, чтобы решить эту проблему?

ПРИМЕЧАНИЕ. Я использую EF для версии .NET 3.5. Также я включаю EF.Utility.CS.ttinclude, доступный в Visual Studio 10.


person Lorenzo    schedule 17.05.2012    source источник


Ответы (2)


Решение найдено. Это правильный код:

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; }
    }
}
person Lorenzo    schedule 28.05.2012

Вместо того, чтобы использовать

navProperty.name

внутри объявления вашего списка

Вы можете использовать

navProperty.ToEndMember

Я думаю, что через это свойство вы сможете найти настоящее имя класса без множественного числа.

person bwbrowning    schedule 17.05.2012
comment
Спасибо за ответ. Вы правы, но..... Если я использую navProperty.ToEndMember.Name, я также получаю "Приказы" :) - person Lorenzo; 17.05.2012
comment
Что это дает вам: navProperty.ToEndMember.TypeUsage.EdmType.Name - person bwbrowning; 17.05.2012
comment
Он возвращает следующую ссылку на строку [CitiesModel.Order], которая содержит правильное имя объекта, но украшена дополнительным текстом.... - person Lorenzo; 18.05.2012