jlopp

I am expiramenting with DLINQ and trying to encapsulate database actions within a single class. As part of this, I have a base class that contains standard fields that will be in every record, in every table (such as primary key, version, etc.), and it also contains the event for notifying DLINQ of changes. When I set this up (code sample below) and try to insert a new record, I get a NullReferenceException thrown (see below). However, if I remove the base class and put its properties in the main class, it works fine. How do I achieve what I am trying to accomplish

Exception

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="System.Data.DLinq"
StackTrace:
at System.Data.DLinq.ProviderBase.SqlBinder.Visitor.AccessMember(SqlMember m, SqlExpression expo)
at System.Data.DLinq.ProviderBase.SqlBinder.Visitor.VisitMember(SqlMember m)
at System.Data.DLinq.ProviderBase.SqlVisitor.Visit(SqlNode node)
....

Code

public class PersistedEntityBase : INotifyPropertyChanging

{

private int _id;

.....

[Column(Storage="_id", Name="id", Id=true, AutoGen=true, DBType="int NOT NULL IDENTITY")]

public int PrimaryKey

{

get

{

return _id;

}

}

}

[Table(Name="company")]

public class Company : PersistedEntityBase

{

private string _name;

public Company() : base()

{

_name = string.Empty;

}

[Column(Name="name")]

public string Name

{

get

{

return _name;

}

set

{

OnPropertyChanging(Name);

_name = value;

....




Re: LINQ Project General DLINQ - Inheritance & NullReferenceException

Mathew Charles

This is not a supported scenario. Later builds, including the upcoming Beta2 will give a better error message letting you know this, something like the message below. Column mappings are only supported on [Table] types, or types derived from them.

Data member 'Int32 PrimaryKey' of type 'PersistedEntityBase' is not part of the mapping for type 'Company'.

Is the member above the root of an inheritance hierarchy






Re: LINQ Project General DLINQ - Inheritance & NullReferenceException

jlopp

This is very interesting because it was decided to make this distinction. I assumed that the class would not matter what it was inheriting from because the DLINQ framework would just see the class Company as having everything it inherited, plus the additional stuff, as the class Company. Is there any chance in the future of supporting this We took a similar approach with Castle's ActiveRecord and it worked nicely. It allows us to make a base class with standard properties and queries that can be used by any entity inheriting from it using reflection and generics.

Fooy, my day just darkened...hehe. I guess we could still have the inheritance, but every class that inherits from the base would have to provide the mapping on its own declared properties. Not the best scenario, but it may have to do.

Thanks!





Re: LINQ Project General DLINQ - Inheritance & NullReferenceException

Edvin

Hi jlopp,

I completely agree with you and I must say that also my day has become very chilly, even if we have almost 40 degrees. I was really hoping that this will works in Beta2, because I see this like a big limitation. Without this you are not able to do some real object programming because object model looks like 1 to 1 mapping between tables and objects. Currently I¡¯m (if I look at your classes) putting int _id; in the PersistedEntityBase as protected field and all other stuff in Company class. This way you can work with PersistedEntityBase as base object, but you will end up with adding additional public property Id to PersistedEntityBase¡­ A lot, lot of duplication¡­.

The other thing I hope that will be changed is with EntityRef. Currently you must define two fields: key field and EntityRef field. Beside that you have two fields it is also very unclear what will be written to database. For example, if you create new object which has EntityRef and you set this entity reference to some object that is already in database, so it is not owned, SubmitChanges will failed because also referenced object will be created, with same primary key. So you must set only key, but than you can¡¯t access EntityRef before SubmitChanges...!!

I think that reference will have to be declared something like this:

struct EntityRef<TKey, TEnity>

{

TKey Key;

TEntity Entity;

}

Also, Association attribute must have some parameters where can you say if referenced object has to be written to database.

nice day

edvin





Re: LINQ Project General DLINQ - Inheritance & NullReferenceException

jlopp

Edvin,

Thanks! I totally agree too and what you described is exactly what I ended up doing. I declared all of PersistedEntityBase members as protected and all of PersistedEntityBase properties for those members as virtual. The Company class then overrides the virtual properties, but just ends up calling the base class implementation. In addition, those properties then have the mappings defined on them so that DLINQ is happy. It works to provide one single place to manage the implementation of the base class, but now we lose the ability to change the mappings in just the base class if we ever wanted to call our standard fields something different in the database or change the datatype, etc... We are both trying to maximize code reuse and minimize duplication.

I cannot say that I have gotten to use the EntityRef stuff yet, but I will get there. Although, I do understand what you are saying and I was wondering how some that would work. Thanks for the heads-up!





Re: LINQ Project General DLINQ - Inheritance & NullReferenceException

Sandy Place

I agree with you jlopp. As having written an in house ORM/Mapper that supports this functionality, I recall that is was not all that difficult to support and extremely useful. We use it to support all kinds of functionality for example our application uses date ranges and has a custom class that supports a bunch of date range methods. SQL does not have any notion of a date range so you typically represent a date range in SQL with a start and an end column. In our application we map start and end to a powerful date range object and inherit from this class. The table just needs to declare a "Start" and "End" column and will inherit all the date range functionality from the base class.