Why is a shadow property being generated when this model implements IEnumerable? - entity-framework

I have the following model classes:
public class Farmer
{
public int ID { get; set; }
public Box Box { get; set; }
}
public class Apple
{
public int BoxID { get; set; }
public Box Box { get; set; }
public int Number { get { return (int)V2.X; } set { V2 = new Vector2(value, 0); } }
public Vector2 V2 {get;set;}
public Farmer Owner { get; set; }
}
public class Box : IEnumerable<Apple>
{
public int ID { get; set; }
public ICollection<Apple> Apples { get; set; }
public IEnumerator<Apple> GetEnumerator()
{
return Apples.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Apples.GetEnumerator();
}
}
When Box implements IEnumerable<'Apple'>, the shadow property FarmerID is added to the Apple table:
migrationBuilder.AddColumn<int>(
name: "FarmerID",
table: "Apples",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Apples_FarmerID",
table: "Apples",
column: "FarmerID");
migrationBuilder.AddForeignKey(
name: "FK_Apples_Farmers_FarmerID",
table: "Apples",
column: "FarmerID",
principalTable: "Farmers",
principalColumn: "ID",
onDelete: ReferentialAction.Restrict);
When I comment out the IEnumerable implementation, the expected migration is created without the FarmerID shadow property. Why is this shadow property being generated and how can I remove it? (I've tried ignoring it, but then I end up getting FarmerID1).
I should mention this is my context class:
public class Context : DbContext
{
public DbSet<Farmer> Farmers { get; set; }
public DbSet<Apple> Apples { get; set; }
public DbSet<Box> Boxes { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"...");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Apple>()
.HasOne(a => a.Box)
.WithMany(a => a.Apples)
.IsRequired();
modelBuilder.Entity<Apple>()
.Ignore(a => a.V2)
.Ignore(a => a.Owner)
.HasKey(a => new { a.BoxID, a.Number });
}
}

The problem is that the ID properties of the Farmer and Box models are not getting mapped which requires EF Core to create a shadow property to Apples to map a farmer to a Box.
To solve the problem, the following can be done:
Rename ID to Id. EF core uses very specific naming conventions to map properties, even in constructors, so if the properties are not named according to the convention expected by EF Core, it will fail.
Add [Key] to ID.
Use Fluent API .HasKey to specify the Key.

Related

EF Core - How to configure a required Foreign Key without a cascaded delete

I'm getting troubles with quite a simple thing. (Entity Framework Core 5)
I wrote following configuration class for a base model from which several child classes are derived.
Models:
abstract public class RecordBase
{
public Guid Id { get; set; }
}
public class Item : RecordBase
{
public string name { get; set; }
}
[NotMapped]
public abstract class LineBase : RecordBase
{
public Guid ItemId { get; set; }
public Item Item { get; set; }
public string Unit { get; set; }
public double Qty { get; set; }
public virtual ICollection<ItemTransaction> ItemTransactions { get; set; } = new Collection<ItemTransaction>();
public virtual ProductDim ProductDim { get; set; }
}
public abstract class OrderLineBase : LineBase
{
public string OrderNum { get; set; }
}
public abstract class JournalLineBase : LineBase
{
public string JournalNum { get; set; }
}
public class SalesOrderLine : OrderLineBase
{
public string CustomerNum { get; set; }
}
public class PurchOrderLine : OrderLineBase
{
public string CustomerNum { get; set; }
}
public class WmsJournalLine : JournalLineBase
{
public string Warehouse { get; set; }
}
public class ItemTransaction : RecordBase
{
public DateTime TransDateTime { get; set; }
public virtual LineBase Line { get; set; }
public string Reference{ get; set; }
}
public class ProductDim : RecordBase
{
public int Configuration { get; set; }
public virtual ICollection<LineBase> LineBases { get; set; }
}
So I'm defining the relation to the ProductDim Table , which must not be nullable.
So I set up the relation make it IsRequired() and set the DeleteBehavior to Restrict.
class LineBaseConfiguration<TEntity> : IEntityTypeConfiguration<TEntity>
where TEntity : LineBase
{
public virtual void Configure(EntityTypeBuilder<TEntity> modelBuilder)
{
modelBuilder.HasOne(x => x.ProductDim)
.WithMany(x => (ICollection<TEntity>)x.LineBases)
.HasForeignKey("ProductDimId")
.IsRequired()
.OnDelete(DeleteBehavior.Restrict);
}
}
The configuration will be applied to the child models of my LineBase model:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
...
modelBuilder.ApplyConfiguration<SalesOrderLine>(new LineBaseConfiguration<SalesOrderLine>());
modelBuilder.ApplyConfiguration<WmsJournalLine>(new LineBaseConfiguration<WmsJournalLine>());
modelBuilder.ApplyConfiguration<PurchOrderLine>(new LineBaseConfiguration<PurchOrderLine>());
...
}
Now when I add the migration to my project the foreign key is generated as ReferentialAction.Cascade.
Migration output:
migrationBuilder.AddForeignKey(
name: "FK_PurchOrderLine_ProductDim_ProductDimId",
table: "PurchOrderLine",
column: "ProductDimId",
principalTable: "ProductDim",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_SalesOrderLine_ProductDim_ProductDimId",
table: "SalesOrderLine",
column: "ProductDimId",
principalTable: "ProductDim",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_WmsJournalLine_ProductDim_ProductDimId",
table: "WmsJournalLine",
column: "ProductDimId",
principalTable: "ProductDim",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
Only if i remove the IsRequired() from my model configuration. The correct RefrentialAction is generated. But then I've made the foreign key property nullable, which I have to avoid.
In this case the migration generates multiple cascades paths. So it is wothless, due i can't apply it to my database.
So is there any other way to get my ForeignKey field was a non-nullable and a correct delete action?
I don't know why, but IsRequired add the foreign key in the entity. All modification do on the foreign key builder (like OnDelete) don't impact the foreign key because it is already build and added in entity. This sound like a bug.
The solution(hack?) is to call IsRequired at last :
modelBuilder.HasOne(x => x.ProductDim)
.WithMany(x => (ICollection<TEntity>)x.LineBases)
.HasForeignKey("ProductDimId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired(); // At last

How to solve EF-Core Code-First table foreign key column missing

I'm learning EF Core and the below is my three POCOs:
public class County
{
[Key]
public int cid { get; set; }
public string cname { get; set; }
}
public class City
{
[Key]
public int cid { get; set; }
public string cname { get; set; }
}
public class People
{
[Key]
public int pid { get; set; }
public string pname { get; set; }
public int cid { get; set; }
public City WhichCity { get; set; }
}
I'm expecting two foreign keys but only got one from City table. How to make it(using annotation or fluent API or whatever) except explicitly define a County variable to People class.
Just want to clarify: you don't need to have navigation properties, i.e., public City City { get; set; } in order to setup relationships. The only things you need are the foreign key and proper configurations.
I think the following configuration would work for you (not tested though):
Entities
Here I also purposely modified your existing classes to follow C# Naming Conventions, if you care. Remember, if you're doing Code First, that means you can have your classes however you want first. You think about persistence later on. Actually I will show you how you can rename classes' properties when you persist them to your database via Configurations.
public class County
{
public int Id { get; set; }
public string Name { get; set; }
}
public class City
{
public int Id { get; set; }
public string Name { get; set; }
}
public class People
{
public int Id { get; set; }
public string Name { get; set; }
public int CityId { get; set; }
// Optional
//public City City { get; set; }
public int CountyId { get; set; }
// Optional
//public County County { get; set; }
}
Configurations
Instead of using Data Annotation, you can use Fluent API with configurations to configure how you want to map your classes back to database.
public class CountyConfiguration : IEntityTypeConfiguration<County>
{
public void Configure(EntityTypeBuilder<County> builder)
{
builder.HasKey(x => x.Id); // Same as using [Key]
builder.Property(x => x.Id)
.HasColumnName("cid"); // If you want to rename to "cid"
builder.Property(x => x.Name)
.IsRequired() // If you want to mark that field required
.HasColumnName("cname"); // If you want to rename to "cname"
builder.ToTable("so_county"); // If you want to rename the table
}
}
public class CityConfiguration : IEntityTypeConfiguration<City>
{
public void Configure(EntityTypeBuilder<City> builder)
{
builder.HasKey(x => x.Id); // Same as using [Key]
builder.Property(x => x.Id)
.HasColumnName("cid"); // If you want to rename to "cid"
builder.Property(x => x.Name)
.IsRequired() // If you want to mark that field required
.HasColumnName("cname"); // If you want to rename to "cname"
builder.ToTable("so_city"); // If you want to rename the table
}
}
public class PeopleConfiguration : IEntityTypeConfiguration<People>
{
public void Configure(EntityTypeBuilder<People> builder)
{
builder.HasKey(x => x.Id); // Same as using [Key]
builder.Property(x => x.Id)
.HasColumnName("pid"); // If you want to rename to "pid"
builder.Property(x => x.Name)
.IsRequired() // If you want to mark that field required
.HasColumnName("pname"); // If you want to rename to "pname"
// Relationship
builder.HasOne<County>() // People has one County
.WithMany() // County has many people
.HasForeignKey<County>(x => x.CountyId); // Foreign key is CountyId
builder.HasOne<City>() // People has one City
.WithMany() // City has many people
.HasForeignKey<City>(x => x.CityId); // Foreign key is CityId
builder.ToTable("so_people"); // If you want to rename the table
}
}
And lastly, you need to apply those configurations OnModelCreating:
public class YourDbContext : DbContext
{
public DbSet<County> Counties { get; set; }
public DbSet<City> Cities { get; set; }
public DbSet<People> People { get; set; }
public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) {}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ApplyConfiguration(new CountyConfiguration());
builder.ApplyConfiguration(new CityConfiguration());
builder.ApplyConfiguration(new PeopleConfiguration());
}
}
DISCLAIM: wrote it by hand. Not tested.

Mapping POCO class which has a (one-to-one) reference to another POCO class with AutoMapper EF Core

My apologies for (perhaps) not using the right terms in the title and this post.
The problem is as follows:
I have a POCO class which has a reference to another table (which is read only). This table has a one-to-one relationship with the other table.
I have set this upo as follow:
public class Commodity
{
public Commodity()
{
}
public long CommodityID { get; set; }
public long CommodityMaterialID { get; set; }
public decimal? SpecficWeight { get; set; }
public OmsCommodityMaterial OmsCommodityMaterial { get; set; }
}
The OmsCommodityMaterial property is the referenced table. This referenced table is also a POCO class which has some other fields, and a porperty back to my own (Commodity) table so I can make a one-to-one relationship with Fluent:
public class OmsCommodityMaterial : OmsBaseClass
{
public OmsCommodityMaterial()
{
}
public long? CommodityMaterialID { get; set; }
public long? CommodityID { get; set; }
public string Name { get; set; }
public long? SortOrder { get; set; }
public Commodity Commodity { get; set; }
}
Fluent (for the one-to-one relation) is set up as follows:
public class MyContext : IdentityDbContext<ApplicationUser>
{
public virtual DbSet<Commodity> Commodity { get; set; }
// Oms classes:
public virtual DbSet<OmsCommodityMaterial> OmsCommodityMaterial { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
public MyContext(DbContextOptions<MyContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Commodity>(entity =>
{
entity.Property(e => e.CommodityID)
.HasColumnName("CommodityID")
.ValueGeneratedOnAdd();
entity.Property(e => e.CommodityMaterialID)
.HasColumnName("CommodityMaterialID");
entity.Property(e => e.SpecficWeight)
.HasColumnName("SpecficWeight")
.HasColumnType("decimal(18, 2)");
entity.HasOne(a => a.OmsCommodityMaterial)
.WithOne(b => b.Commodity)
.HasForeignKey<Commodity>(b => b.CommodityMaterialID);
});
}
}
In my endpoint I want to do a GET of all values which return the specific fields of my own table (Commodity) and all the fields of the referenced table (OmsCommodityMaterial).
For this purpose I created a ViewModel (also because else I get a circular reference as I found out in this post: ERR_CONNECTION_RESET returning Async including object child collections) which looks as follow:
public class CommodityViewModel
{
public long CommodityID { get; set; }
public long CommodityMaterialID { get; set; }
public decimal? SpecficWeight { get; set; }
public OmsCommodityMaterial OmsCommodityMaterial { get; set; }
}
For the ViewModels I am using AutoMapper, but I actually have no clue how I can map / return the list of the above ViewModel.
UPDATE
I ended up eliminating the Circular reference error by adding the [JsonIgnore] attribute to the public virtual Commodity Commodity { get; set; } property in the OmsCommodityMaterial POCO class. Now I can get all the needed column values:
return await this.Context.Commodity
.Include(i => i.OmsCommodityMaterial)
.ToListAsync();
Though, I suppose this is not the way to go. There should be a better solution for this by creating a ViewModel that retrieves the Commodity columns and (some) of the referenced OmsCommodityMaterial columns without falling in the Circular Reference error, but how (using AutoMapper)?

ef core 1.1 Autogenerated column using ValueGeneratedOnAdd

Using EfCore 1.1, I am trying to have a autogenerated column using ValueGeneratedOnAdd. The problem is i am always getting value as "0". Do i have to manually do anything with the database table ?
Here is my model
public class Contact
{
public int Id { get; set; }
// This needs to be auto generated
public Int32 ContactIndex { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public DateTime LastAccessed { get; set; }
}
This is how my OnModelCreating looks like
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>()
.Property(c => c.ContactIndex)
.ValueGeneratedOnAdd();
// I tried following as well but it did't work
// .HasDefaultValueSql("IDENTITY(int, 1,1)");
;
}
ok I figured how to do it, but i really wanted to do that without using any annotations, and i still cannot figure out how to do it without annotations on model. So here is my solution.
You need to annotate your filed in the model like following
public class Contact
{
public int Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int32 ContactIndex { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public DateTime LastAccessed { get; set; }
}
and add OnModelCreating in your context class. This will tell entity framework to ignore the column while adding or updating records. Make sure you calling method .ValueGeneratedAddOrUpdate( ). If you use only .ValueGeneratedAdd( ) you will get errors while making updates.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>()
.Property(c => c.ContactIndex)
.ValueGeneratedOnAddOrUpdate();
;
}
Generate and run your migrations and your migrations should include "SqlServerValueGenerationStrategy.IdentityColumn"
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ContactIndex",
table: "Contact",
nullable: false,
defaultValue: 0)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
}

literal or constant as part of composite key in EF code first

I am relatively new to the Code First approach to Entity Framework. I have used the Database First approach for a while now, but the Code First seems to be a better fit for the application I am currently developing. I am working with an existing MS SQL database, and I am not allowed to make any changes whatsoever to the database. The reason why I am using Code First is because the Fluent API allows me to dynamically assign a table name to a class.
That said, I have a predicament where I need to assign a relationship between 2 tables. One table, ArCodes, has a composite key made up of the CodeType and the Code (both are strings). The CodeType column determins the type of code and the Code column is the identifier unique to the code type.
public class ArCode {
[Column("cod_typ", Order = 0), Key]
public string CodeType { get; set; }
[Column("ar_cod", Order = 1), Key]
public string Code { get; set; }
[Column("desc")]
public string Description { get; set; }
}
The other table, Invoices, needs to have a relationship to the ArCodes table for both a "ship via" code and a "terms" code.
public class Invoice {
[Column("pi_hist_hdr_invc_no"), Key]
public int InvoiceNumber { get; set; }
[Column("shp_via_cod")]
public string ShipViaCode { get; set; }
public ArCode ShipVia { get; set; }
[Column("terms_cod")]
public string TermsCode { get; set; }
public ArCode Terms { get; set; }
}
I would like to setup the relationship for both the "ShipVia" property and the "Terms" property. However, I am not sure how to do so in regards to the CodeType portion of the composite key. For "ship via" codes the Code Type should be "S", and code "terms" codes, the code type should be "T".
I have tried the following in by DB Context, but it did not work:
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
// setup the table names
modelBuilder.Entity<ArCode>().ToTable("ARCODS" + CompanyCode);
modelBuilder.Entity<Invoice>().ToTable("IHSHDR" + CompanyCode);
//
// setup the relationships
//
// 1 Invoice <--> 0-1 Ship Via AR Codes
modelBuilder.Entity<Invoice>()
.HasOptional(invoice => invoice.ShipVia)
.WithMany()
.HasForeignKey(invoice => new { TheType = "S", invoice.ShipViaCode })
;
base.OnModelCreating(modelBuilder);
}
Any help would be appreciated.
Update #1
Ok, I reduced my code to its simplest form, and I followed the solution as provided by #GertArnold.
public abstract class ArCode {
[Column("cod_typ")]
public string CodeType { get; set; }
[Column("ar_cod")]
public string Code { get; set; }
[Column("terms_desc")]
public string TermsDescription { get; set; }
[Column("terms_typ")]
public string TermsType { get; set; }
[Column("shp_via_desc")]
public string ShipViaDescription { get; set; }
[Column("tax_desc")]
public string TaxDescription { get; set; }
}
public class TermsCode : ArCode { }
public class ShipViaCode : ArCode { }
public class Invoice {
[Column("pi_hist_hdr_invc_no"), Key]
public int InvoiceNumber { get; set; }
[Column("hdr_invc_dat")]
public DateTime InvoiceDate { get; set; }
[Column("shp_via_cod")]
public string ShipViaCode { get; set; }
public ShipViaCode ShipVia { get; set; }
[Column("terms_cod")]
public string TermsCode { get; set; }
public TermsCode Terms { get; set; }
public Invoice() {
}
}
public class PbsContext : DbContext {
public DbSet<Invoice> Invoices { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Invoice>().ToTable("IHSHDR");
modelBuilder.Entity<ArCode>().HasKey(r => r.Code).ToTable("ARCODS");
modelBuilder.Entity<TermsCode>().Map(m => m.Requires("CodeType")
.HasValue("T").HasColumnType("varchar").HasMaxLength(1).IsRequired())
.ToTable("ARCODS");
modelBuilder.Entity<ShipViaCode>().Map(m => m.Requires("CodeType")
.HasValue("S").HasColumnType("varchar").HasMaxLength(1).IsRequired())
.ToTable("ARCODS");
base.OnModelCreating(modelBuilder);
}
public PbsContext()
: base("name=PbsDatabase") {
}
}
However, the following code returns an error:
PbsContext context = new PbsContext();
var invoice = context.Invoices.OrderByDescending(r => r.InvoiceDate).FirstOrDefault();
error 3032: Problem in mapping fragments starting at line 28:Condition member 'ArCode.cod_typ' with a condition other than 'IsNull=False' is mapped. Either remove the condition on ArCode.cod_typ or remove it from the mapping.
If I remove the "CodeType" column from the ArCode class and change all "CodeType" references to the database column name of "cod_typ" within the OnModelCreating event, then the statement above executes without error. However, invoice.ShipVia and invoice.Terms will both be null event though there is a matching record in the database.
Update #2
public abstract class ArCode {
[Column("ar_cod")]
public string Code { get; set; }
[Column("terms_desc")]
public string TermsDescription { get; set; }
[Column("terms_typ")]
public string TermsType { get; set; }
[Column("shp_via_desc")]
public string ShipViaDescription { get; set; }
[Column("tax_desc")]
public string TaxDescription { get; set; }
}
public class TermsCode : ArCode { }
public class ShipViaCode : ArCode { }
public class Invoice {
[Column("pi_hist_hdr_invc_no"), Key]
public int InvoiceNumber { get; set; }
[Column("hdr_invc_dat")]
public DateTime InvoiceDate { get; set; }
[Column("shp_via_cod")]
public ShipViaCode ShipVia { get; set; }
[Column("terms_cod")]
public TermsCode Terms { get; set; }
public Invoice() {
}
}
public class PbsContext : DbContext {
public DbSet<Invoice> Invoices { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Invoice>().ToTable("IHSHDR");
modelBuilder.Entity<ArCode>().HasKey(r => r.Code).ToTable("ARCODS");
modelBuilder.Entity<TermsCode>().Map(m => m.Requires("CodeType")
.HasValue("T").HasColumnType("varchar").HasMaxLength(1).IsRequired())
.ToTable("ARCODS");
modelBuilder.Entity<ShipViaCode>().Map(m => m.Requires("CodeType")
.HasValue("S").HasColumnType("varchar").HasMaxLength(1).IsRequired())
.ToTable("ARCODS");
base.OnModelCreating(modelBuilder);
}
public PbsContext()
: base("name=PbsDatabase") {
}
}
Now, the following code returns an error:
PbsContext context = new PbsContext();
var invoice = context.Invoices.OrderByDescending(r => r.InvoiceDate).FirstOrDefault();
EntityCommandExecutionException - Invalid column name 'ShipVia_Code'. Invalid column name 'Terms_Code'.
What you want is impossible for EF. ArCode has a composite key, so any association to it will have to use two Properties. That means that in Invoice you'd need four properties (two pairs) to refer to the two ArCode objects. But two of these properties (those for CodeType) are not backed up by columns in the database, so EF can not map them.
But... there is a way that may help you out. You could create two derived classes from ArCode and let Invoice refer to those by single-property associations. But then you have to divert from the model as such and fool EF a bit by defining a single key:
public abstract class ArCode { ... } // abstract!
public class TermsCode : ArCode { }
public class ShipViaCode : ArCode { }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Invoice>().ToTable("IHSHDR");
modelBuilder.Entity<Invoice>().HasOptional(i => i.Terms).WithOptionalDependent().Map(m => m.MapKey("terms_cod"));
modelBuilder.Entity<Invoice>().HasOptional(i => i.ShipVia).WithOptionalDependent().Map(m => m.MapKey("shp_via_cod"));
modelBuilder.Entity<ArCode>().HasKey(a => a.Code).ToTable("ARCODS");
modelBuilder.Entity<TermsCode>().Map(m => m.Requires("CodeType")
.HasValue("T").HasColumnType("varchar").HasMaxLength(1).IsRequired())
.ToTable("ARCODS");
modelBuilder.Entity<ShipViaCode>().Map(m => m.Requires("CodeType")
.HasValue("S").HasColumnType("varchar").HasMaxLength(1).IsRequired())
.ToTable("ARCODS");
base.OnModelCreating(modelBuilder);
}
public class Invoice
{
[Column("pi_hist_hdr_invc_no"), Key]
public int InvoiceNumber { get; set; }
public ShipViaCode ShipVia { get; set; }
public TermsCode Terms { get; set; }
}
This may work for you if you don't have to insert ARCODS records through EF. It won't allow you to insert records with identical Codes, although the database would allow it. But I expect the content of ARCODS to be pretty stable and maybe it is enough to fill it with a script.