Type convertsion from string

  • Thread starter Thread starter Andrus
  • Start date Start date
It was considering I've been playing with LINQ pretty much non-stop
for the last several days... and equally daft considering I have 2008
express open on my taskbar, but failed to check...

But feel free to release those LINQ chapters to [ahem] help?

Marc
 
Marc,
I guess at the end of the day your requirement (to add dynamic
properties to the entity) is very hard to reconcile with a
"regular" (fixed) entity model. I'm trying to think of ways out of the
hole, but:
* runtime properties - not supported by ActiveRecord / NHibernate

You also wrote earlier that runtime properties are not supported in Linq, is
this true ?
* subclassing - in theory should work; currently seeing an NHibernate
issue [probably fixable with NHibernate knowledge], but might also be
hard to get the FindAll() etc working unless you do this on the
subclass (perhaps forwarding to a private method on the base-class)

I was unable to make AR FindAll() work with Activerecord/NH. FindAll() is
static method and does not find properties in child class.

I was able to extend linq entity class at runtime using the code below.
In design time I have dummy assembly EntityExtension.dll which contains

using System.Data.Linq.Mapping;
[Table(Name = "Customer")]
public class Customer : EntityBase.CustomerWithStandardProperties {}

This dummy assembly is deleted when application is deployed.
In runtime I use AssemblyResolve to create extended entity using code below.

Is this best solution ?

Andrus.

using System;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;

class Program {

static void Main(string[] args) {

// delete dummy assembly which is used in design time only.
// this is required to run form VS2008 IDE.
System.IO.File.Delete("EntityExtension.dll");
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Form f = new Form();
DataGridView dgv = new DataGridView();
f.Controls.Add(dgv);
dgv.DataSource = GetData();
Application.Run(f);
}

static Assembly CurrentDomain_AssemblyResolve(object sender,
ResolveEventArgs args) {

if (!args.Name.StartsWith("EntityExtension") ) {
return null;
}
return CreateAssembly();
}

static Assembly CreateAssembly() {

CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters compilerParameters = new CompilerParameters();
compilerParameters.GenerateInMemory = true;
compilerParameters.ReferencedAssemblies.Add("EntityBase.dll");
// use postgresql linq provider
compilerParameters.ReferencedAssemblies.Add(@"C:\dblinq2007\DbLinq\bin\DbLinq.Pgsql.Prototype.dll");
compilerParameters.ReferencedAssemblies.Add("System.dll");
compilerParameters.ReferencedAssemblies.Add(@"c:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.5\System.Data.Linq.dll");

CompilerResults compilerResults =
provider.CompileAssemblyFromSource(compilerParameters,
@"
using System;
using System.Data.Linq.Mapping;

[Table(Name = ""customer"")]
public class Customer : EntityBase.CustomerWithStandardProperties {

protected string _a_a;

// sample dynamic property
[Column(Name = ""a_a"", DbType = ""character"")]

public string A_a {
get { return _a_a; }
set { _a_a = value; _isModified_ = true; }
}

// sample calculated field
public string xxNimi {
get { return ""Mr "" + Nimi; }
}

public Customer(string id, string a_a):base(id) {
_a_a = a_a;
}}
");

return compilerResults.CompiledAssembly;
}

public object GetData() {
mydb db;
const string connStr = "server=localhost;";
db = newmydb(connStr);
var q = from k in db.Customers select k;
return q.ToList();
}
}
}
 
You also wrote earlier that runtime properties are not supported in
Linq, is this true ?
Yes. System.Linq.Expressions.MemberExpression has a "public MemberInfo
Member {get;}" it only supports reflection based lookup. Given that
much of the time (at the usage-level) LINQ is used at compile-time, it
makes sense - and allows for simpler (and very efficient) compilation
to delegates, but it frustrated me too.
In runtime I use AssemblyResolve to create extended entity using
code below.
Is this best solution ?
I'd be very cautious of this myself - you are providing a substitute
assembly. As long as you get the name + version correct (and strong
name if signed, but then you need to deploy the snk) then it will
probably work, but it doesn't seem a typical use-case. The main use of
AssemblyResolve would be to load the /expected/ dll (perhaps requiring
download) from alternative locations. If you can get it to work, then
great!

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top