Hi,

I having an error creating a custom entity. The error is 'Xtensive.Orm.EntitySet<dotestweb.model.file>' does not contain a constructor that takes 0 arguments'

Thank you,

Richard

Here is my code

[HierarchyRoot]
public class File : Entity
{

    [Field(Length = 100)]
    public string Name { get; set; }

    public Folder ParentFolder;

    public File() : base()
    {

    }

    public File(Session session): base(session)
    {

    }

}

public class File_EntitySet : EntitySet<File>
{

    public new bool Add(File file)
    {

        return true;
   }

}

asked Jun 12 '13 at 13:07

rasxte's gravatar image

rasxte
20151617


7 Answers:

Hello Richard,

EntitySet type does not have parameterless constructor. That's why compiler gives you an error.

Custom entity sets should have the following constructor:

public File_EntitySet(Entity owner, FieldInfo field) : base(owner, field)
{
}

answered Jun 13 '13 at 03:51

Denis%20Krjuchkov's gravatar image

Denis Krjuchkov
179325

Denis,

Thank you for your answer.

I am having an error during run time that says that my custom entityset is null. The code is the following:

Folder.Files.Add(file);

The error claims that the Files EntitySet is null.

Thank you for your help.

Richard

Here is the full code:

Execution code:

Folder folder = new Folder(session);

folder.Name = "Docs2";

File file = new File(session);

file.Name = "Agenda.doc";

folder.Files.Add(file); <-- The error is here.

Class Definition:

[HierarchyRoot]
public class Folder : Entity
{
     [Field, Key]
     public int Id { get; private set; }

    [Field(Length = 100)]
    public string Name { get; set; }

    [Field]
    public int FileCount { get; set; }

    public File_EntitySet Files { get; private set; }

    public Folder() : base()
    {

    }

    public Folder(Session session) : base(session)
    {

    }

}

[HierarchyRoot]
public class File : Entity
{
    [Field, Key]
    public int Id { get; private set; }

    [Field(Length = 100)]
    public string Name { get; set; }

    public Folder ParentFolder;

    public File() : base()
    {

    }

    public File(Session session): base(session)
    {

    }

}

public class File_EntitySet : EntitySet<File>
{

    public File_EntitySet(Entity owner, Xtensive.Orm.Model.FieldInfo field) : base(owner, field) 
    {

    }

    public new bool  Add(File file) 
    {

        return true;

    }

}

answered Jun 13 '13 at 23:18

rasxte's gravatar image

rasxte
20151617

You need to add a [Field] attribute to the Files property to make it persistent (in other words DO-managed). The same applies to Folder ParentFolder field. It should be a auto-property (not a field) and marked with [Field] attribute.

(Jun 14 '13 at 05:27) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Denis,

Thank you for the answer.

Adding the [Field] attribute on the files property gets rid of the null error.

I added the [Field] attribute to the ParentFolder property but I get compiler error that the [Field] declaration is not valid on this declaration type.

Here is the code:

[HierarchyRoot] public class File : Entity { [Field, Key] public int Id { get; private set; }

    [Field(Length = 100)]
    public string Name { get; set; }

    [Field]
    public Folder ParentFolder;

    public File() : base()
    {

    }

    public File(Session session): base(session)
    {

    }

}

I also having problems saving values to the backend database.

I am working on Asp.net project created with the DO Template for WebSite Application. I am relying on the SessionManager, DomainBuilder, the code in the Global.asax file and the settings in the web.config file to handle automatic transactions and session management. The folowing code saves values to the database only once. Meaning no matter how many times I run the project it does not create a new record for the entities in the database. Everytime I run the project it takes the existing records and replaces them with the new values I specify in code.

Thank you for your help.

Here is the code:

 public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var session = Xtensive.Orm.Session.Current;

        Folder folder = new Folder(session);

        folder.Name = "Docs3";

        File file = new File(session);

        file.Name = "Agenda.doc";

        folder.Files.Add(file);

} }

The Folder.Files.Add(file) does not save the file entity to Files EntitySet.

answered Jun 14 '13 at 16:05

rasxte's gravatar image

rasxte
20151617

Your ParentFolder field still is not an auto-property. Your File_EntitySet has custom Add method which hides method from the base class. Since base method is not called DataObjects.Net can't track adding new item to this entity set.

Also you might consider setting paired association between File and Folder. To do so add [Association(PairTo="ParentFolder")] to your Files property in Folder class. This would automatically maintain Files collection according to ParentFolder fields in File class and vice-versa.

(Jun 15 '13 at 04:01) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Dennis,

Thank very much for your help.

I applied the changes and the Folder.Files.Add(file) works now... But there is still a problem saving new entities. I don't understant why if I define a new entity and run the code the first time an entity is created. When I run the code the second time instead of creating a new entity what happens is the the existing entity is updated but no new entity is created.. You can see in my code I create Folder.Name = "Folder3" but no new records is created instead "Folder2" is replaced with "Folder3".

Here is the code:

public partial class _Default : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)
{
var session = Xtensive.Orm.Session.Current;

     Folder folder = new Folder(session);

     folder.Name = "Folder3";

     File file = new File(session);

     file.Name = "Agenda.doc";

     folder.Files.Add(file);

} }

answered Jun 17 '13 at 11:58

rasxte's gravatar image

rasxte
20151617

I'd start with checking your DomainConfiguration if it has DomainUpgradeMode=Recreate then obviously database would be recreated each time application starts.

(Jun 18 '13 at 04:52) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Hi Denis,

That's was the problem...

Thank very much for your help. I am migrating from DO 3.9.... I have a lot to catch up to.

Do you have any equivalent class as the DataService Class in DO 4.x or is it something not needed in DO 4.x, especially when working asp.net.

Thanks again,

Richard

answered Jun 18 '13 at 19:01

rasxte's gravatar image

rasxte
20151617

There are two options for this.

DO has its own simple dependency injection container that could be used to emulate DataService feature from DO 3.9.

Here is an example:

http://dosamples.codeplex.com/SourceControl/latest#Sources/Services/SessionBoundService/Services/MySessionService.cs http://dosamples.codeplex.com/SourceControl/latest#Sources/Services/SessionBoundService/Program.cs

(Jun 19 '13 at 06:18) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Internal container has very limited features. We have no plans to extend it because our product is ORM not DI-container.

You could use any container you like and associate it with session automatically.

Domain.SessionOpen += (sender, e) => e.Session.Extensions.Set<MyContainer>(CreateContainer(e.Session));

And then anywhere in the code when you have session:

var container = session.Extensions.Get<MyContainer>();
(Jun 19 '13 at 06:18) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

ASP.NET MVC has it's own DI container infrastructure as well. You might want to use it instead. If you use our SessionManager which provides session and transaction on each request, you could simply register Session as a service in your container using custom factory method that calls Session.Demand(). Make sure your container don't dispose session otherwise SessionManager would be confused.

(Jun 19 '13 at 06:18) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Hi Denis,

Thanks again for all of your help.

Could you please show me some sample code as to how to register SessionManager.Session as a Service in my own container.

Thanks much,

Richard

answered Jun 19 '13 at 20:56

rasxte's gravatar image

rasxte
20151617

It depends on what container you're going to use. This is a large topic and mostly unrelated with DataObjects.Net. If have no idea here is a short guide: http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection

Here is an example of registration with Unity:

container.RegisterType<Session>(
   new TransientLifetimeManager(),
   new InjectionFactory(c => Session.Demand()));
(Jun 21 '13 at 09:07) Denis Krjuchkov Denis%20Krjuchkov's gravatar image

Hi Denis,

Thank you very much for your help.

Richard

answered Jun 23 '13 at 23:48

rasxte's gravatar image

rasxte
20151617

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

powered by OSQA