Hello, some questions about dynamically extended entities have been already answered here and here. Our use case doesn't differ from the already answered questions: we want to add, or possibly remove, some fields from an existing entity at runtime. We would like to ask you if you have a sample with the code generation approach stated in 2 that we can use as a quick start. Also we would like to ask you if all databases are suitable for dynamically extended entities using dataobjects.net and code generation. Our development platform will be mainly postgresql with possibly postgresql and/or oracle as production deployment db.

Thanks

asked Feb 17 '14 at 06:25

fpretto's gravatar image

fpretto
5223

edited Feb 17 '14 at 06:26


One Answer:

Hello,

here is a short but complete example of adding and removing fields dynamically.

There are no limitations for DB however if you're going to change your model you'll need to perform a regular upgrade over the database.

Unfortunately due to techinal limitations dynamic fields are not fully usable in LINQ unless there is a real property defined for the field in question.

using System;
using System.Linq;
using Xtensive.Orm;
using Xtensive.Orm.Building;
using Xtensive.Orm.Building.Definitions;
using Xtensive.Orm.Configuration;

namespace DynamicEntitySample
{
  [HierarchyRoot]
  public class DynamicEntity : Entity
  {
    [Key, Field]
    public long Id { get; private set; }

    [Field]
    public string FieldToRemove { get; set; }

    public DynamicEntity(Session session)
      : base(session)
    {
    }
  }

  public class MyModule : Module
  {
    public override void OnDefinitionsBuilt(BuildingContext context, DomainModelDef model)
    {
      // Removing existing field
      var dynamicEntityType = model.Types[typeof (DynamicEntity)];
      var fieldToRemove = dynamicEntityType.Fields["FieldToRemove"];
      dynamicEntityType.Fields.Remove(fieldToRemove);
      // Adding new field
      dynamicEntityType.DefineField("FieldToAdd", typeof (string));
    }
  }

  internal static class Program
  {
    private static void Main(string[] args)
    {
      var configuration = new DomainConfiguration("sqlserver",
        "Data Source=localhost;Initial Catalog=DO-Tests;Integrated Security=True;MultipleActiveResultSets=True");
      configuration.UpgradeMode = DomainUpgradeMode.Recreate;
      configuration.Types.Register(typeof (DynamicEntity).Assembly);
      var domain = Domain.Build(configuration);

      using (var session = domain.OpenSession())
      using (var tx = session.OpenTransaction()) {
        var entity = new DynamicEntity(session);
        // Setting dynamic field value
        entity["FieldToAdd"] = "Hello dynamic world!";
        tx.Complete();
      }

      using (var session = domain.OpenSession())
      using (var tx = session.OpenTransaction()) {
        var entity = session.Query.All<DynamicEntity>().Single();
        // Reading dynamic field value
        Console.WriteLine(entity["FieldToAdd"]);
        tx.Complete();
      }
    }
  }
}

answered Feb 20 '14 at 04:39

Denis%20Krjuchkov's gravatar image

Denis Krjuchkov
179325

edited Feb 20 '14 at 04:40

Thanks for the answer. Similarly to what was suggested in one of the previous answer, we would like to use "Dynamic LINQ" (or DLINQ) to express our queries. If you have a sample with the runtime code emit of the relevant entities (with the new property) and a DLINQ example it would be handy, but it's enough if you confirm us that is doable. If it concerns, my activated HW ID is 42B1-BA64-ECF6-E609-94D4.

(Feb 24 '14 at 03:05) fpretto fpretto's gravatar image
1

If you want to dynamically generate Entity types you'll need to replicate what DO performs during post-compilation:

1) Property accessors are replaced with GetFieldValue/SetFieldValue calls.

2) Special protected constructors are added. These simply call parent constructors of the same signature.

3) Special factory methods are added. These use constructors from (2).

4) Existing constructors are modified to call DO methods before and after user code.

(Feb 24 '14 at 09:51) Denis Krjuchkov Denis%20Krjuchkov's gravatar image
1

This is not completely trivial task, but definitely could be implemented. Besides that I see only one minor technical issue: DataObjects.Net will complain if your types are not processed by PostSharp. This is done for merely for user convenience. Such restriction could be relaxed for dynamically generated types.

(Feb 24 '14 at 09:51) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Denis, I was a bit forgetting the AOP related operations performered by PostSharp, so yes: it's not trivial but it's doable. As an advice: It would be awesome If you manage to find some time in the following days/weeks to prepare a sample with this approach and post it on https://dosamples.codeplex.com/ .

(Feb 25 '14 at 03:45) fpretto fpretto's gravatar image

Unfortunately we don't have resources for that at the moment. This looks like a good feature for DataObjects.Net Extensions. However the earliest moment this could be implemented is after the release of DataObjects.Net 5.

(Feb 27 '14 at 03:50) Denis Krjuchkov Denis%20Krjuchkov's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

Subscription:

Once you sign in you will be able to subscribe for any updates here

Tags:

×6

Asked: Feb 17 '14 at 06:25

Seen: 3,002 times

Last updated: Feb 27 '14 at 03:50

powered by OSQA