Dears, Binding combo with Queryresult was never a prob in DO3.x, we can create oql and n then execute, but i am not able to achieve the same now. like i have a combo <cc1:objectlookup id="ctldept" runat="server" bindingexpression="Rec.Section" textfield="Name" objectname="Department" width="300px"></cc1:xobjectlookup> i could easily write the query like: string oql = " Select " + ObjectName + " instances where (1=1) ";q = new Query(_session, sQL);qr = q.Execute(QueryOptions.SkipLocked);

But now with linq in action: how can i get this : my aim is to generically bind the combo with their datasource based on their ObjectName. ctldept.DataSource = from dept in Query.All<department>() select new { Id = dept .Id, NameEn = dept .NameEn };
i want to make this code generic ,so that i can bind any controls. How will i pass <department> generically. and i just want to return two columns that is TextField and ValueField ,these values we will get from control properties.

any suggestions pls help thanks HAN


Updated at 21.07.2010 16:48:00

okay i think i will use: public void FillCombo(Session session) {
var command = session.Services.Get<directsqlaccessor>().CreateCommand();
command.CommandText = "select "+ ValueField +","+TextField+" from Department"; DbDataReader dr = command.ExecuteReader(); this.Items.Clear(); while (dr.Read()) { this.Items.Add(dr["TextField"].ToString(), dr["ValueField"]); } dr.Close(); }

My only issue to make this work is that the table name is different than object name. how can we get table name from object name, if i access metadata then i might get the tablename. pls help thanks HAN


Updated at 22.07.2010 8:46:51

Dear Alex, thanks for your reply. Alex, i just want developers to set three properties for my textbox control i.e ObjectName which is a string, TextFieldName and FieldName , all are string properties. now since the object name is in string, how can i get entity or entitytype from string, if i get this ,then rest your code i understood which will help me to just bring two columns from the database.

pls help

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Jul 21 '10 at 14:20

HannanKhanji's gravatar image

HannanKhanji
54141317


One Answer:

Alex (Xtensive) wrote:

1) It's a bad idea to use DirectSqlAccessor here. LINQ is definitely better, since you shouldn't care about the mapping. You should just build the query (expression tree there) dynamically.

Just yesterday we've added quite useful version of Query.All method: Query.All(Type entityType). It can be used with dynamic query for exactly such cases:

var entityType = typeof (AnyEntityType); // i.e. type is defined in runtime
var query =  Query.All(type).Select("new(TextField as TextField, ValueField as ValueField)"); // dynamic condition

// Let's perform query and cast the result to static type we know
var result = new List<KeyValuePair<string,string>>();
foreach (dynamic d in query)
  result.Add(new KeyValuePair<string,string>(d.TextField, d.ValueField);

2) You can acquire all the mapping information using entity.TypeInfo property (TypeInfo object). All TypeInfo objects describing persistent types are available via Domain.Model.Types collection.


mahdness wrote:

Ok, now we're talking about something really interesting.

1) Query.All() This was pretty easy to implement ourselves with typeof(Query).GetMethod("All", BindingFlags.Static).MakeGenericType(entityType) But good anyway.

2) Select("new(TextField as TextField.....") So, if I have a Customer entity with fields (Name, PhoneNumber, AssignedTo) where AssignedTo is of type Employee, and Employee has fields (Name, Salary), can I do:

Query.All(typeof(Customer)).Select("new(Name, PhoneNumber, AssignedTo, AssignedTo.Name, AssignedTo.Salary)")

Or how am I supposed to do that? And what if I have a type I'd like to project it to (i.e. if I do NOT want to use anonymous types)?

3) What's the best practice for implementing a Where(...) clause? Using Dynamic LINQ? Or have you developed another option?

4) Prefetching In #2 above, will the query automatically prefetch the required fields (namely AssignedTo.Name and AssignedTo.Salary from the referenced Employee type)? If not, how can we specify prefetch?

Thanks guys!


Alex (Xtensive) wrote:

2 hannankhanji:

Use either domain.Model.Types[string shortTypeName] or domain.Model.Types.Find(string fullTypeName) methods to get TypeInfo object (our persistent type model).

TypeInfo.UnderlyingType is .NET Type object corresponding to it.

I forgot to mention that changes related to Query.All(Type type) aren't available yet (will be available in the nearest update).

2 mahdness:

> This was pretty easy to implement ourselves

Almost true: our LINQ translator handles its usage e.g. in subqueries as well ;)

**> Query.All(typeof(Customer)).Select("new(Name...

Or how am I supposed to do that? And what if I have a type I'd like to project it to (i.e. if I do NOT want to use anonymous types)?**

Yes, nearly. Unfortunately, you can't project it to non-anonymous type with DynamicLINQ - because it doesn't support this (i.e. it isn't dependent on us).

Hmm, it seems I forgot to mention that example relies on DynamicLINQ as well.

> What's the best practice for implementing a Where(...) clause? Using Dynamic LINQ? Or have you developed another option?

Yes, DynamicLINQ is the simplest option. Another is, well, you know - manual expression tree construction.

> ... will the query automatically prefetch the required fields (namely AssignedTo.Name and AssignedTo.Salary from the referenced Employee type)?

Hopefully :) Actually this depends on expression generated by DynamicLINQ. As far as I can judge, it must be identical to the expression in string. Thus DO will prefetch all the fields used there.

answered Jul 22 '10 at 07:48

Editor's gravatar image

Editor
46153156157

Dear alex, Wrt to your reply, when i replace this:

grid.DataSource = 
  from gender in Query.All<Gender>()
  select gender;

to

grid.DataSource = 
  from gender in Query.All<DomainBuilder.Domain.Model.Types["Gender"].UnderlyingType>() 
  select gender;

it throws me error.

Invalid expression term ')'. Operator '<' cannot be applied to operands of type 'Method Group' and 'System.Type'

pls help.

(Sep 19 '10 at 06:27) HannanKhanji HannanKhanji's gravatar image

Err... You should look closer at LINQ and generics...

You can't use instance as generic parameter value anywhere in .NET, including our Query.All<T>(). You need a type there.

But you can build an Expression instance in runtime, that corresponds exactly the described method call (i.e. call of All<T>() method on Query type, where T is any type you want).

Also, you can compile and execute it in runtime - to get the IQueryable, that can be use further (e.g. decorated by other combinators, or simply enumerated).

(Sep 22 '10 at 06:53) Alex Yakunin Alex%20Yakunin's gravatar image

But this is pretty far from DO4 nature - i.e. the problem you face is related to .NET Framework usage, but not to DO4 itself.

(Sep 22 '10 at 06:54) Alex Yakunin Alex%20Yakunin's gravatar image

I'd like to help you, but you need pretty deep explanation of how all this stuff works. So I'd recommend you to read some good book about this.

E.g. C# 4.0 in a Nutshell - its authors also developed LINQPad - a great tool for testing LINQ. Btw, it's pretty easy to use DO with LINQPad as well (although we're thinking about special provider for it).

(Sep 22 '10 at 06:54) Alex Yakunin Alex%20Yakunin'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

powered by OSQA