Is it possible to create a projection method? [linq2sql] - linq-to-sql

i want to be able to do such a projection:
var result = from record in MyTable
select MapTo( record );
/*
select new RecordModel( )
{
RecordId = record.Id,
Property1 = record.Property1
};
*/
private RecordModel MapTo( MyTable dbRecord )
{
return new RecordModel( )
{
RecordId = dbRecord.Id,
Property1 = dbRecord.Property1
};
}
but i always get a 'NotSupportedException' (has no supported translation to sql).
I'm not sure if this is even possible but it would be nice^^
Maybe this is possible when i use an expression but i don't know how to code such an expression.

Linq tries to add the method to the query and sees it cannot be translated to Sql.
To be able to execute any CLR method in the Linq query, you need to execute the sql part of it first, so that you operate on in-memory objects. Like this:
var result = from record in MyTable.ToList()
select MapTo(record);
Anything that forces MyTable to enumerate its entries should work.

Related

LINQ for SQL statement that returns single scalar value

I want to execute the following select:
SELECT 0 as Value
What is the correlating syntax in LINQ for SQL?
Edit
I want to use the correlating LINQ for SQL statement in a Concat() call like this
var c = (from a in mytable select a.Value).Concat(select 0).Sum();
As you can see, Concat(select 0) obviously doesn't compile. Any ideas?
Edit 2
David suggested to use a simple collection instead. I've tried
private decimal[] mZeroDecimals = new[] { 0.0m };
...
public void MyFunction()
{
var c = (from a in mytable select a.Value).Concat(mZeroDecimals).Sum();
...
but it throws an exception Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.
You're not actually querying anything, so there is no LINQ involved. You're just creating an anonymous object with a single property called Value:
var obj = new { Value = 0 };
Edit: Based on your comment, it sounds like you want this object in a collection. That doesn't make it a LINQ query (since you're still not querying anything), but you can declare a collection just as easily as a single object. Something like this:
var coll = new[] { new { Value = 0 } };
Since this is a collection, it can be used with any of the enumerable extension methods that LINQ uses, which sounds like what you're trying to do.

how to execute MongoDB Query in RDBMS Driver way

In RDMS if I have to execute "Select emp_name from Employee where empid=100". I would do this,
String query = "Select emp_name from Employee where empid=100"
Statement stmt = DriverManager.getConnection(db, user, password).createStatement();
result = stmt.executeQuery(query);
How can I do the same in MongoDB where I get the query like "Employee.find({'empid:1000'},{emp_name:1})
Currently this is the code I'm using, in which I have to write the 'where' and 'select' part I mean dbObj(where) and projectdbObj(projecttion Or select part) separately.
DBObject dbObj = (DBObject) JSON.parse("{'employee.empid':'1000'}");
DBObject projectdbObj = (DBObject) JSON.parse("{'emp_name':1}");
try{
MongoCollection<Document> coll = mongoClient.getDatabase("Company" ).getCollection("Employee");
FindIterable<Document> cursor = coll.find((Bson) dbObj).projection((Bson) projectdbObj);
cursor.forEach(new Block<Document>() {
#Override
public void apply(final Document document) {
System.out.print(document);
}
});
}
Please help to optimize the code.
You can use Filters builder to build 'where' part and Projections builder to build 'select' part in MongoDB 3.0 without create object separately. Please refer below eg:
FindIterable<Document> cursor = coll.find(Filters.eq("employee.empid",1000)).projection(Projections.fields(Projections.include("emp_name"),Projections.excludeId());

Linq to Sql: Join, why do I need to load a collection

I have 2 tables that I need to load together all the time, the both must exist together in the database. However I am wondering why Linq to Sql demands that I have to load in a collection and then do a join, I only want to join 2 single tables where a record where paramid say = 5, example...
var data = _repo.All<TheData>(); //why do I need a collection/IQueryable like this?
var _workflow = _repo.All<WorkFlow>()
.Where(x => x.WFID== paramid)
.Join(data, x => x.ID, y => y.WFID, (x, y) => new
{
data = x,
workflow = y
});
I gues then I need to do a SingleOrDefault()? If the record is not null pass it back?
I Understand the Sql query comes out correctly, is there a better way to write this?
NOTE: I need to search a table called Participants to see if the loggedonuser can actually view this record, so I guess I should leave it as this? (this is main requirement)
var participant = _repo.All<Participants>();
.Any(x=> x.ParticipantID == loggedonuser.ID); //add this to above query...
The line var data = _repo.All<TheData>(); is something like saying 'start building query against the TheData table'.
This function returns you an IQueryable which will contain a definition of the query against your database.
So this doesn't mean you load the whole TheData table data with this line!
The query will be executed the moment you do something like .Count(), .Any(), First(), Single(), or ToList(). This is called deferred execution.
If you would end your query with SingleOrDefault() this will create a sql query that joins the two tables, add the filter and select the top most record or null(or throw an error if there are more!).
You could also use Linq instead of query extension methods.
It would look like:
var data = _repo.All<TheData>();
var _workflow = from w in _repo.All<WorkFlow>()
join t in _repo.All<TheData> on w.Id equals t.WFID
where x.WIFD = paramid
select new
{
data = t,
workflow = x
});

Can any one provide me LINQ to update data inside xml column?

I have a table Table1 has columns ID (int) and XMLTEXT of xml type
Can any one provide me LINQ query which is equivalent to below sql query
Update Table1 set XMLTEXT .modify('delete (/root/child1/child2)')
where ID=1001
In Linq2SQL, something like this should work.
long ProductID = 1;
ORM.Table1 p = context.Table1s.Where(o => o.ID == ProductID).FirstOrDefault();
if(p != null) {
p.XMLTEXTe.Element("child2").Remove();
// Need to do this so Linq picks up on the data change
// as it doesnt implement the correct XElement data changed event handler
// and thus won't submit the changes made if you dont do the reassignment!
p.XMLTEXT = new XElement(p.XMLTEXT);
context.SubmitChanges();
}

Populate JOIN into a list in one database query

I am trying to get the records from the 'many' table of a one-to-many relationship and add them as a list to the relevant record from the 'one' table.
I am also trying to do this in a single database request.
Code derived from Linq to Sql - Populate JOIN result into a List almost achieves the intended result, but makes one database request per entry in the 'one' table which is unacceptable. That failing code is here:
var res = from variable in _dc.GetTable<VARIABLE>()
select new { x = variable, y = variable.VARIABLE_VALUEs };
However if I do a similar query but loop through all the results, then only a single database request is made. This code achieves all goals:
var res = from variable in _dc.GetTable<VARIABLE>()
select variable;
List<GDO.Variable> output = new List<GDO.Variable>();
foreach (var v2 in res)
{
List<GDO.VariableValue> values = new List<GDO.VariableValue>();
foreach (var vv in v2.VARIABLE_VALUEs)
{
values.Add(VariableValue.EntityToGDO(vv));
}
output.Add(EntityToGDO(v2));
output[output.Count - 1].VariableValues = values;
}
However the latter code is ugly as hell, and it really feels like something that should be do-able in a single linq query.
So, how can this be done in a single linq query that makes only a single database query?
In both cases the table is set to preload using the following code:
_dc = _db.CreateLinqDataContext();
var loadOptions = new DataLoadOptions();
loadOptions.LoadWith<VARIABLE>(v => v.VARIABLE_VALUEs);
_dc.LoadOptions = loadOptions;
I am using .NET 3.5, and the database back-end was generated using SqlMetal.
This link may help
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
Look under join operators. You'll probably have to change from using extension syntax other syntax too. Like this,
var = from obj in dc.Table
from obj2 in dc.Table2
where condition
select