TPH, Is possible such a data structure like this - entity-framework

I'm trying to create a tables using Code-First in EF.
I created many versions of my code but I put here only one. It almost works, it means this code creates sql but doesn't work properly.
What I want to get:
I have 2 simple tables : Order and Payer.
Also, I want to create a third table based on foreign keys of these 2.
It wont create it that meet the following rules:
Each Order has exactly one Base Payer. (So I don't need complex key in this case. OrderId can exist only one in this table if record is type of (Base)OrderPayer
Each Order can have 0,1 or many (Extra)OrderPayer. ( So in this case i need put into table complex Key (OrderId + PayerId)
here is my last C# code
public class Order
{
[Key]
public int OrderId { get; set; }
public string OrderName { get; set; }
public virtual BaseOrderPayer BaseOrderPayer { get; set; }
public virtual ICollection<ExtraOrderPayer> ExtraOrderPayers { get; set; }
}
public class Payer
{
[Key]
public int PayerId { get; set; }
public string PayerName { get; set; }
}
public abstract class OrderPayer
{
[Column(Order = 0), Key, ForeignKey("Order")]
public int OrderId { get; set; }
public virtual Order Order { get; set; }
}
public class BaseOrderPayer : OrderPayer
{
[ForeignKey("BasePayer")]
public virtual int? BasePayerId { get; set; }
public virtual Payer BasePayer { get; set; }
}
public class ExtraOrderPayer : OrderPayer
{
[Column(Order = 1), Key, ForeignKey("ExtraPayer")]
public virtual int? ExtraPayerId { get; set; }
public virtual Payer ExtraPayer { get; set; }
}
and SQL that was generated by Update-Database -Script
CREATE TABLE [dbo].[OrderPayers] (
[OrderId] [int] NOT NULL,
[ExtraPayerId] [int],
[BasePayerId] [int],
[Discriminator] [nvarchar](128) NOT NULL,
[Order_OrderId] [int],
CONSTRAINT [PK_dbo.OrderPayers] PRIMARY KEY ([OrderId])
)
CREATE TABLE [dbo].[Payers] (
[PayerId] [int] NOT NULL IDENTITY,
[PayerName] [nvarchar](30),
CONSTRAINT [PK_dbo.Payers] PRIMARY KEY ([PayerId])
)
CREATE TABLE [dbo].[Orders] (
[OrderId] [int] NOT NULL IDENTITY,
[OrderName] [nvarchar](30),
[BaseOrderPayer_OrderId] [int],
CONSTRAINT [PK_dbo.Orders] PRIMARY KEY ([OrderId])
)
CREATE INDEX [IX_OrderId] ON [dbo].[OrderPayers]([OrderId])
CREATE INDEX [IX_ExtraPayerId] ON [dbo].[OrderPayers]([ExtraPayerId])
CREATE INDEX [IX_BasePayerId] ON [dbo].[OrderPayers]([BasePayerId])
CREATE INDEX [IX_Order_OrderId] ON [dbo].[OrderPayers]([Order_OrderId])
CREATE INDEX [IX_BaseOrderPayer_OrderId] ON [dbo].[Orders]([BaseOrderPayer_OrderId])
ALTER TABLE [dbo].[OrderPayers] ADD CONSTRAINT [FK_dbo.OrderPayers_dbo.Payers_BasePayerId] FOREIGN KEY ([BasePayerId]) REFERENCES [dbo].[Payers] ([PayerId])
ALTER TABLE [dbo].[OrderPayers] ADD CONSTRAINT [FK_dbo.OrderPayers_dbo.Payers_ExtraPayerId] FOREIGN KEY ([ExtraPayerId]) REFERENCES [dbo].[Payers] ([PayerId])
ALTER TABLE [dbo].[OrderPayers] ADD CONSTRAINT [FK_dbo.OrderPayers_dbo.Orders_Order_OrderId] FOREIGN KEY ([Order_OrderId]) REFERENCES [dbo].[Orders] ([OrderId])
ALTER TABLE [dbo].[OrderPayers] ADD CONSTRAINT [FK_dbo.OrderPayers_dbo.Orders_OrderId] FOREIGN KEY ([OrderId]) REFERENCES [dbo].[Orders] ([OrderId])
ALTER TABLE [dbo].[Orders] ADD CONSTRAINT [FK_dbo.Orders_dbo.OrderPayers_BaseOrderPayer_OrderId] FOREIGN KEY ([BaseOrderPayer_OrderId]) REFERENCES [dbo].[OrderPayers] ([OrderId])
but his SQL it doesn't even work
I can't insert Order because it need OrderPayer and vice versa :)
Is it possible to fix it according to my expectations ?
p.s.
the tables are very simplified, in fact they contain many other fields

Related

How to block creation redundant FK Constraint in EF TPH Code First

I use in some project EF code First with TPH (in part of classes)
I have class like this:
namespace Billing.Model.Domain.Entities.BilProject
{
[Table("ProjectPriceList")]
public abstract class ProjectPriceList
{
[Key, Column("ProjectId", Order = 0)]
public int ProjectId { get; set; }
[Key, Column("PriceListId", Order = 1)]
public int PriceListId { get; set; }
[Key, Column("PriceListSourceType", Order = 2)]
public int PriceListSourceType { get; set; }
[ForeignKey("PriceListSourceType")]
public virtual BillingProjectCode PriceListSourceTypeCode { get; set; }
public int AddUsrnm { get; set; }
public DateTime AddTmstmp { get; set; }
[ForeignKey("ProjectId")]
public virtual BillingProject BillingProject { get; set; }
public virtual SnapShotPriceList SnapShotPriceList{ get; set; }
}
public class BillingProjectPriceList : ProjectPriceList
{
[ForeignKey("PriceListId")]
public virtual PriceList PriceList { get; set; }
}
public class EstimateProjectPriceList : ProjectPriceList
{
}
}
When I try to generate sql code to create a data base by
Update-Database -Script from console
I receive this SQL as result:
CREATE TABLE [dbo].[ProjectPriceList] (
[ProjectId] [int] NOT NULL,
[PriceListId] [int] NOT NULL,
[PriceListSourceType] [int] NOT NULL,
[AddUsrnm] [int] NOT NULL,
[AddTmstmp] [datetime] NOT NULL,
[Discriminator] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_dbo.ProjectPriceList] PRIMARY KEY ([ProjectId], [PriceListId], [PriceListSourceType])
)
CREATE INDEX [IX_ProjectId] ON [dbo].[ProjectPriceList]([ProjectId])
CREATE INDEX [IX_PriceListId] ON [dbo].[ProjectPriceList]([PriceListId])
CREATE INDEX [IX_PriceListSourceType] ON [dbo].[ProjectPriceList]([PriceListSourceType])
ALTER TABLE [dbo].[ProjectPriceList] ADD CONSTRAINT [FK_dbo.ProjectPriceList_dbo.BillingProject_ProjectId] FOREIGN KEY ([ProjectId]) REFERENCES [dbo].[BillingProject] ([ProjectId]) ON DELETE CASCADE
ALTER TABLE [dbo].[ProjectPriceList] ADD CONSTRAINT [FK_dbo.ProjectPriceList_dbo.BillingProjectCode_PriceListSourceType] FOREIGN KEY ([PriceListSourceType]) REFERENCES [dbo].[BillingProjectCode] ([CodeId]) ON DELETE CASCADE
ALTER TABLE [dbo].[ProjectPriceList] ADD CONSTRAINT [FK_dbo.ProjectPriceList_dbo.PriceList_PriceListId] FOREIGN KEY ([PriceListId]) REFERENCES [dbo].[PriceList] ([PriceListId]) ON DELETE CASCADE
The last FK Constraint is redudant and make me trouble if i try add new EstimateProjectPriceList.
My question is
How to stop create this FK by some code Data Annotations or Fluent Api in OnModelCreating ?
Thnx for any help..

How to many-to-many relation with the same class with Entity-framework

I would like to create many-to-many relation with .NET MVC EF. I have Client model (it could be employer or employee or colleague etc., company or person). So any of the client can have employees or employer. I am not sure how to set this relation in EF.
My models (parts of db context):
public partial class Client
{
public long Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ClientRelation> TargetClientRelations { get; set; }
public virtual ICollection<ClientRelation> SourceClientRelations { get; set; }
}
public enum ClientRelationType
{
Employer_Employee
}
public class ClientRelation
{
public long Id { get; set; }
public virtual Client Client { get; set; }
public virtual Client TargetClient { get; set; }
public ClientRelationType ClientRelationType { get; set; }
}
The problem is EF creates this relation table. I gues I should create some mapping..
CREATE TABLE [dbo].[ClientRelations](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Client_Id] [bigint] NULL,
[TargetClient_Id] [bigint] NULL,
[Client_Id1] [bigint] NULL,
[Client_Id2] [bigint] NULL,
[ClientRelationType] [int] NOT NULL,
CONSTRAINT [PK_dbo.ClientRelations] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ClientRelations] ADD DEFAULT ((0)) FOR [ClientRelationType]
GO
ALTER TABLE [dbo].[ClientRelations] WITH CHECK ADD CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_Client_Id] FOREIGN KEY([Client_Id])
REFERENCES [dbo].[Clients] ([Id])
GO
ALTER TABLE [dbo].[ClientRelations] CHECK CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_Client_Id]
GO
ALTER TABLE [dbo].[ClientRelations] WITH CHECK ADD CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_Client_Id1] FOREIGN KEY([Client_Id1])
REFERENCES [dbo].[Clients] ([Id])
GO
ALTER TABLE [dbo].[ClientRelations] CHECK CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_Client_Id1]
GO
ALTER TABLE [dbo].[ClientRelations] WITH CHECK ADD CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_Client_Id2] FOREIGN KEY([Client_Id2])
REFERENCES [dbo].[Clients] ([Id])
GO
ALTER TABLE [dbo].[ClientRelations] CHECK CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_Client_Id2]
GO
ALTER TABLE [dbo].[ClientRelations] WITH CHECK ADD CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_TargetClient_Id] FOREIGN KEY([TargetClient_Id])
REFERENCES [dbo].[Clients] ([Id])
GO
ALTER TABLE [dbo].[ClientRelations] CHECK CONSTRAINT [FK_dbo.ClientRelations_dbo.Clients_TargetClient_Id]
GO
You need to add some additional configuration to your model to specify which property is related with.
Using Data Anotations you will need to use InverseProperty attribute:
public class ClientRelation
{
public long Id { get; set; }
[InverseProperty("SourceClientRelations")]
public virtual Client Client { get; set; }
[InverseProperty("TargetClientRelations")]
public virtual Client TargetClient { get; set; }
public ClientRelationType ClientRelationType { get; set; }
}
If you decide go for Fluent Api then your configurations would be:
modelBuilder.Entity<ClientRelation>()
.HasOptional(l => l.TargetClient)
.WithMany(p => p.TargetClientRelations);
modelBuilder.Entity< ClientRelation>()
.HasOptional(l => l.Client)
.WithMany(p => p.SourceClientRelations);

EF7 - Custom column name for HasOne relationship

How do you specify a custom column name with a HasOne relationship in EF7?
Consider the following sample classes:
public class House
{
public int Id { get; set; }
public int BedroomCount { get; set; }
public Address Address { get; set; }
}
public class Address
{
public int Id { get; set; }
public string StreetName { get; set; }
public string StreetNumber { get; set; }
}
And this fluent configuration:
modelBuilder.Entity<House>()
.HasOne(x => x.Address)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
Which leads to this DB configuration:
CREATE TABLE [House] (
[Id] int NOT NULL IDENTITY,
[AddressId] int,
[BedroomCount] int NOT NULL,
CONSTRAINT [PK_House] PRIMARY KEY ([Id]),
CONSTRAINT [FK_House_Address_AddressId] FOREIGN KEY ([AddressId]) REFERENCES [Address] ([Id]) ON DELETE CASCADE);
CREATE TABLE [Address] (
[Id] int NOT NULL IDENTITY,
[StreetName] nvarchar(max),
[StreetNumber] nvarchar(max),
CONSTRAINT [PK_Address] PRIMARY KEY ([Id]));
How do I specify a column name other than "AddressId" on the House table? I cannot find a method similar to HasColumnName like there is on non-navigation properties.
I'm using Entity Framework 7 RC1-Final.
You can use Data Annotations to configure the foreign key of your relationship.
public int AddressID { get; set; }
[ForeignKey("AddressID")]
public Address Address { get; set; }
This requires a property that will be used as the foreign key in your relationship. Also, note that it is recommended that you have a explicit foreign key for your relationships other than a shadow foreign key. This will prevent you to have a lot of problems when inserting/updating since you don't need to set the entire navigation property Address to save a House entity. See the problem here
Not tested but perhaps this could work (can't find a way to install EF7 right now)
modelBuilder.Entity<House>()
.HasOne(x => x.Address)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
.HasForeignKey(x => x.AddressID);
You can check here for more examples: Foreign Key Relationships EF7
You can get property first from modelBuilder.Entity<House>().Metadata.GetProperties() list and then set its name
property.Relational().ColumnName = "YouCustomId"

Entity Framework generates SQL with incorrect column name

I have a couple of tables Questions and QuestionQueryParameters I am trying to setup with the entity framework. Essentially I want to see what questions rely on this one and what questions does this question rely on.
As things stand I get an invalid column error "Question_Id1" I am assuming I have not set the foreign key relationships up correctly but I am new to the entity frame work and no amount of "fiddling" has worked yet.
Tables
CREATE TABLE [dbo].[Questions](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Text] [nvarchar](max) NULL,
[Section] [nvarchar](max) NULL,
[Order] [int] NOT NULL,
[Active] [bit] NOT NULL,
[Mandatory] [bit] NOT NULL,
[QuestionType_Id] [int] NULL,
[EntityType_Id] [int] NOT NULL,
[ImportTimestamp] [datetime] NULL,
[ImportUser_Id] [int] NULL,
[Question_Id] [int] NULL,
[DisplayMenuType] [bit] NULL,
[Abbrev] [nvarchar](max) NULL,
[Searchable] [bit] NULL,
CONSTRAINT [PK_Questions] PRIMARY KEY CLUSTERED
(
[Id] ASC,
[EntityType_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Questions] WITH CHECK ADD CONSTRAINT [FK_Questions_EntityType] FOREIGN KEY([EntityType_Id])
REFERENCES [dbo].[EntityType] ([Id])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Questions] CHECK CONSTRAINT [FK_Questions_EntityType]
GO
ALTER TABLE [dbo].[Questions] WITH CHECK ADD CONSTRAINT [FK_Questions_QuestionTypes] FOREIGN KEY([QuestionType_Id])
REFERENCES [dbo].[QuestionTypes] ([Id])
GO
ALTER TABLE [dbo].[Questions] CHECK CONSTRAINT [FK_Questions_QuestionTypes]
GO
ALTER TABLE [dbo].[Questions] WITH CHECK ADD CONSTRAINT [FK_Questions_User] FOREIGN KEY([ImportUser_Id])
REFERENCES [dbo].[Users] ([Id])
GO
ALTER TABLE [dbo].[Questions] CHECK CONSTRAINT [FK_Questions_User]
GO
CREATE TABLE [dbo].[QuestionQueryParameters](
[QuestionQueryParameter_Id] [int] IDENTITY(1,1) NOT NULL,
[Question_Id] [int] NOT NULL,
[EnablingQuestion_Id] [int] NULL,
[EntityType_Id] [int] NOT NULL,
CONSTRAINT [PK__Question__2FBBD18F3E723F9C] PRIMARY KEY CLUSTERED
(
[QuestionQueryParameter_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[QuestionQueryParameters] WITH CHECK ADD CONSTRAINT [FK_QuestQueryParam_Questions] FOREIGN KEY([Question_Id], [EntityType_Id])
REFERENCES [dbo].[Questions] ([Id], [EntityType_Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[QuestionQueryParameters] CHECK CONSTRAINT [FK_QuestQueryParam_Questions]
GO
ALTER TABLE [dbo].[QuestionQueryParameters] WITH CHECK ADD CONSTRAINT [FK_QuestQueryParam_QuestionsEnabling] FOREIGN KEY([EnablingQuestion_Id], [EntityType_Id])
REFERENCES [dbo].[Questions] ([Id], [EntityType_Id])
GO
ALTER TABLE [dbo].[QuestionQueryParameters] CHECK CONSTRAINT [FK_QuestQueryParam_QuestionsEnabling]
GO
Classes
public class Question
{
[Key, Column(Order = 0)]
public int Id { get; set; }
public string Text { get; set; }
public string Section { get; set; }
public int Order { get; set; }
public bool Active { get; set; }
public bool Mandatory { get; set; }
public bool Searchable { get; set; }
public virtual QuestionType QuestionType { get; set; }
// public virtual TemplateType TemplateType { get; set; }
public virtual List<QuestionChoice> QuestionChoices { get; set; }
public virtual List<QuestionEnabler> QuestionEnablers { get; set; }
public virtual List<QuestionChoiceQuery> QuestionChoicesQuery { get; set; }
[Key, Column(Order = 1)]
public virtual EntityType EntityType { get; set; }
public DateTime? ImportTimestamp { get; set; }
public int? ImportUser_Id { get; set; }
public virtual List<Question> EnabledQuestions { get; set; }
public virtual List<QuestionQueryParameter> QuestionParameters { get; set; }
public bool DisplayMenuType { get; set; }
public string Abbrev { get; set; }
[InverseProperty("Question")]
public virtual ICollection<QuestionQueryParameter> ReliesOnMe { get; set; }
[InverseProperty("EnablingQuestion")]
public virtual ICollection<QuestionQueryParameter> IRelyOn { get; set; }
}
public class QuestionQueryParameter
{
[Key]
public int QuestionQueryParameter_Id { get; set; }
public virtual Question Question { get; set; }
public virtual Question EnablingQuestion { get; set; }
public virtual EntityType EntityType { get; set; }
}
Entity framework can't tell which foreign key to match up so it makes its own. The solution is InverseProperty which you have, but you need to point to the foreign key, not the navigation property:
[InverseProperty("Question_Id")]
public virtual ICollection<QuestionQueryParameter> ReliesOnMe { get; set; }
[InverseProperty("EnablingQuestion_Id")]
public virtual ICollection<QuestionQueryParameter> IRelyOn { get; set; }
https://msdn.microsoft.com/en-us/data/jj591583.aspx#Relationships
If you want to rename the FK columns in your DB without declaring them in your entity, you should use Fluent API instead Data Annotations to configure those relationships. To change the names you need to use the Map method:
modelBuilder.Entity<QuestionQueryParameter>()
.HasRequired(s => s.Question)
.WithMany(s => s.ReliesOnMe).Map(ca=>ca.MapKey("Question_Id","EntityType_Id")); // Change the FK column names here
modelBuilder.Entity<QuestionQueryParameter>()
.HasRequired(s => s.EnablingQuestion)
.WithMany(s => s.IRelyOn).Map(ca=>ca.MapKey("EnablingQuestion_Id","EntityType_Id")); // Change the FK column names here
Due to you are using a composite PK in the Question entity, the name of the FK columns in the MapKey method must be specified in the same order that the primary keys in the Question entity.

EF Code First: The INSERT statement conflicted with the FOREIGN KEY constraint

This is my trial project using breeze/angular/EF. I don't understand why I get this error because I thought I had the same structure working before.
public class TshirtOrder
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<OrderItem> OrderItems { get; set; }
}
public class OrderItem
{
public int Id { get; set; }
[ForeignKey("Type")]
public int TshirtTypeId { get; set; }
public virtual TshirtType Type { get; set; }
[ForeignKey("Size")]
public int TshirtSizeId { get; set; }
public virtual TshirtSize Size { get; set; }
public double UnitPrice { get; set; }
public int Quantity { get; set; }
[ForeignKey("TshirtOrder")]
public int TshirtOrderId { get; set; }
public TshirtOrder TshirtOrder { get; set; }
}
The table definition looks like this:
CREATE TABLE [dbo].[TshirtOrder] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (MAX) NULL,
CONSTRAINT [PK_dbo.TshirtOrder] PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[OrderItem] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[TshirtTypeId] INT NOT NULL,
[TshirtSizeId] INT NOT NULL,
[UnitPrice] FLOAT (53) NOT NULL,
[Quantity] INT NOT NULL,
[TshirtOrderId] INT NOT NULL,
CONSTRAINT [PK_dbo.OrderItem] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.OrderItem_dbo.TshirtType_TshirtTypeId] FOREIGN KEY ([TshirtTypeId]) REFERENCES [dbo].[TshirtType] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.OrderItem_dbo.TshirtSize_TshirtSizeId] FOREIGN KEY ([TshirtSizeId]) REFERENCES [dbo].[TshirtSize] ([Id]) ON DELETE CASCADE,
CONSTRAINT [FK_dbo.OrderItem_dbo.TshirtOrder_TshirtOrderId] FOREIGN KEY ([TshirtOrderId]) REFERENCES [dbo].[TshirtOrder] ([Id]) ON DELETE CASCADE
);
This is how it gets saved in Breeze datacontext:
function _createTshirtOrder() {
var order = manager.createEntity("TshirtOrder");
order.orderItems.push(createOrderItem(lookups.tshirtTypes[0], lookups.tshirtSizes[0], 10));
common.saveEntity(order);
return order;
function createOrderItem(type, size, unitPrice) {
var item = manager.createEntity("OrderItem");
item.type = type;
item.size = size;
item.unitPrice = unitPrice;
item.quantity = 0;
return item;
}
}
Here is the exact error:
{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_dbo.OrderItem_dbo.TshirtOrder_TshirtOrderId\". The conflict occurred in database \"dbbb\", table \"dbo.TshirtOrder\", column 'Id'.\r\nThe statement has been terminated."}
So, where is the problem?
I don't know what your "saveEntity" method looks like but I'm guessing it calls
entityManager.saveChanges([order]);
If so, then the problem is that you are only saving the order and NOT the orderItem as well, because you told it to only save the one order. Breeze tracks any changes to the entityManager so a better solution is usually to just let Breeze figure it out for you. i.e.
entityManager.saveChanges(); or entityManager.saveChanges(null, ... );
Which will save all added, modified or deleted records in the entityManager.
Alternately you can specify all of the entities you want saved.
entityManager.saveChanges([order, orderItem1, orderItem2, ... ]);