How can I use two different data contexts in one LINQ request? - c#

Can anybody help me with next: how can I use two different data contexts in one LINQ request?
using (var db = new DataMapDataContext(Connection))
{
using (var dbAdd = new DataMapDataContext(ConnectionAdd))
{
return (from i in dbAdd.ITEMs
join p in db.U_OTT_PINs on i.ITEMNO equals p.PIN_CODE
where p.PIN_TYPE == Utils.PinItem
select ...
}
}
Is it possible?
UPDATE:
I resolved my issue, but not with different data contexts:
var listPinnedItems = new List<string>();
using (var db = new DataMapDataContext(Connection))
{
listPinnedItems = (from lpi in db.U_OTT_PINs
where lpi.PIN_TYPE == Utils.PinItem
select lpi.PIN_CODE).ToList();
}
using (var dbAdd = new DataMapDataContext(ConnectionAdd))
{
return (from i in dbAdd.ITEMs
where listPinnedItems.Contains(i.ITEMNO)
...

I'm afraid LINQ to SQL is not made for querying across different databases. See below for possible workaround?
http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/3a15002c-704d-49f9-a8cc-0d2bde186e1d

I don't believe so - these two different contexts could be involved in different transactions in the same database, or even talking to completely different database instances. How would it construct SQL to work across the two?
If you could explain what you're trying to do, we may be able to help you more.

It's possible to use two datacontexts, but you can't do database queries across both at the same time. You could however get the data involved in both queries and query the objects using generic linq statements (linq2objects).

This is one of those questions that shouldn't be answered without first asking "What are you trying to achieve?".
Are both datacontexts pointing to the same database or different databases?
If they connect to same database and the only reason why you have two is that you have separated your entities then you can use just one DC to query a table that 'belongs' to another datacontext. Just use GetTable and L2S will resolve the mappings based on class and member attributes.
If they point to different databases on the same server and the login you're connecting to one of the DBs as has rights to read from the second DB you can include the table from one database in a datacontext based on another db by simply adding the database name as a prefix in the .dbml file.

Related

EF6 mapping similar tables into one entity

I'm making an application that uses legacy database, using EF6 database first, .Net C#.
The database has two versions: the old and the new one. In the new one some tables were modified and renamed. E.g. old one has tables like: work, order, item etc. and new one work_t, order_t and item_t.
The content of corresponding tables is very similar, in the new ones some new columns were added and some were removed. So my application is supposed to work with both kind of databases as I use only the columns that are presented in both versions.
I was wondering if there is any decent way to hide those table pairs behind some interface or something to avoid doing 2 implementations of LINQ coding.
This is not exactly creating one entity out of 2 tables, because only one table is presented in the database at a time. I want to have single piece of code to address either one of the similar tables.
Here's some pseudo code for what I'm after:
public workDTO GetWork(int workId)
{
MyEntities db = new MyEntities();
// for old version it will go like
var work = db.work.Where(a => a.id == workId);
// for new version it will go like
var work = db.work_t.Where(a => a.id == workId);
return Mapper.Map(work, workDTO);
}
So the idea is to have just one method and one LINQ implementation for both tables.
Yes , You can do it by giving a column attribute in entity framework:
Read here
Update :
You can use the .ToTable() method:
modelBuilder.Entity().ToTable("t_Department");
Source: MSDN: http://msdn.microsoft.com/en-us/data/jj591617.aspx

Connect to Database with Connection String to use LINQ

I have a connection string and I want to use LINQ to query a remote database. In the Microsoft example they use the DataContext class. However the DataContext does not appear in Intellisense. It says that it uses 'System.Data.Linq` but I am not seeing that either. http://msdn.microsoft.com/en-us/library/bb350721(v=vs.110).aspx
Is there a Hello World example for using a connection string and LINQ?
public void SimpleQuery()
{
var connectionString = #"Server=10.1.10.1;database=Mydatabase;uid=myusername;password=mypassword;";
DataContext dc = new DataContext(connectionString);
var q =
from n in dc.table
select n;
Console.WriteLine(n);
}
Well, that is not how it works or at least it is not that simple.
In order to be able to run linq queries against your DB, first you need to map your db tables to dot net classes.
You can do that in various ways, for example you can use Linq to Sql, or Entity framework.
For EF, you need to decide which EF approach you are going to use (Model First,Code First etc.) Then you should configure your settings and create your db context.Take a look at Entity Framework documentation for more details...

How to use two different database with relation in one asp.net mvc c# application

How to use two different database with relation in one asp.net mvc c# application
One of the benefits of using Entity Framework 4.0 is that it can handle data from multiple tables, or as in your case, multiple databases. Here is one how-to article. There is somewhat of a learning curve, but many people like this approach, and Microsoft seems to be dedicated to it for the future.
Basically, using EF allows you to do the data mapping in its model, abstracting all the database and table joins from you. You get business objects with class and property names that you can understand, and that are easier to code against.
static New table1DataContext Context1 =
new table1DataContext ("ConnectionString1");
static table2DataContext Context2 = new table2DataContext ("ConnectionString2");
//Linq statement in c#
var query = from a in table1DataContext.table1 from b in table2DataContext.table2
where a.ID == b.ID
select new { a, b };

C# linq to sql - selecting tables dynamically

I have the following scenario: there are a database that generates a new logTable every year. It started on 2001 and now has 11 tables. They all have the same structure, thus the same fields, indexes,pk's, etc.
I have some classes called managers that - as the name says - manages every operation on this DB. For each different table i have a manager, except for this logTable which i have only one manager.
I've read a lot and tried different things like using ITable to get tables dynamically or an interface that all my tables implements. Unfortunately, i lose strong-typed properties and with that i can't do any searches or updates or anything, since i can't use logTable.Where(q=> q.ID == paramId).
Considering that those tables have the same structure, a query that searches logs from 2010 can be the exact one that searches logs from 2011 and on.
I'm only asking this because i wouldn't like to rewrite the same code for each table, since they are equal on it's structure.
EDIT
I'm using Linq to SQL as my ORM. And these tables uses all DB operations, not just select.
Consider putting all your logs in one table and using partitioning to maintain performance. If that is not feasible you could create a view that unions all the log tables together and use that when selecting log data. That way when you added a new log table you just update the view to include the new table.
EDIT Further to the most recent comment:
Sounds like you need a new DBA if he won't let you create new SPs. Yes I think could define an ILogTable interface and then make your log table classes implement it, but that would not allow you do GetTable<ILogTable>(). You would have to have some kind of DAL class with a method that created a union query, e.g.
public IEnumerable<ILogTable> GetLogs()
{
var Log2010 = from log in DBContext.2010Logs
select (ILogTable)log;
var Log2011 = from log in DBContext.2011Logs
select (ILogTable)log;
return Log2010.Concat(Log2011);
}
Above code is completely untested and may fail horribly ;-)
Edited to keep #AS-CII happy ;-)
You might want to look into the Codeplex Fluent Linq to SQL project. I've never used it, but I'm familiar with the ideas from using similar mapping techniques in EF4. YOu could create a single object and map it dynamically to different tables using syntax such as:
public class LogMapping : Mapping<Log> {
public LogMapping(int year) {
Named("Logs" + year);
//Column mappings...
}
}
As long as each of your queries return the same shape, you can use ExecuteQuery<Log>("Select cols From LogTable" + instance). Just be aware that ExecuteQuery is one case where LINQ to SQL allows for SQL Injection. I discuss how to parameterize ExecuteQuery at http://www.thinqlinq.com/Post.aspx/Title/Does-LINQ-to-SQL-eliminate-the-possibility-of-SQL-Injection.

LINQ to Entities - Support for Closures (Lambdas)?

I've been working around a problem I have when using LINQ to Entities when using closures.
Apparently, L2E does not support closures. Meaning:
var users = from user in UserRepository.FindAll()
select new UserDTO
{
UserId = user.UserId,
Tickets = from ticket in TicketRepository.FindAll()
where ticket.User == user
select new TicketDTO
{
TicketId = ticket.TicketId
}
};
(NOTE: The "where"-clause is where the problem exists. I am not allowed to compare an entity to another entity because they are not EF primitive types. Only things like Int32, Guid etc. is allowed.)
, is not valid because I cannot compare 'ticket.User' to 'user'
This is simply an example of the problem I have, and I realize that I could compare on the Id, since this a primitive type, as opposed to a closure.
In reality my scenario is alot more complex than this, but this is the scenario I need to solve for now.
A work-around I found online is using a subquery. That DOES work, but for my scenario it's not very effective.
Question:
Do any of you know if:
Entity Framework 4 will support Closures in LINQ to Entities?
There is a better solution to this problem than using sub-queries?
Any additional knowledge you have on this topic will be greatly appreciated!
This is not a problem directly related to closures. The problem is (probably) that you are mixing Entity Framework entities and your data transfer objects. The LINQ provider tries to convert the expression tree of your query into SQL statements and fails because it cannot separate the data transfer objects from the entities and the database, of course, cannot deal with the data transfer objects, too.
I suggest to make the separation much cleaner - at first fetch the data from the database using LINQ to Entity and maybe anonymous types if required, then switch to LINQ to Objects to construct data transfer objects from the retrieved data and all should be fine. Something like the following. (Just to note - I am (safely) assuming the repositories return IQueryable<T>s (else the whole stuff should not work at all).)
var result = UserRepository
.FindAll()
.Select(user => new
{
UserId = user.UserId,
TicketIds = TicketRepository
.FindAll()
.Where(ticket => ticket.User.UserId == user.UserId)
.Select(ticket => ticket.TicketId)
});
Transforming this query result into data transfer objects is now straight forward. Note that the users are compared via the IDs because the Entity Framework does (not yet) support comparisons by reference.
The problem here is that L2E doesn't support reference equality of materialized objects vs. objects in the DB, so you need to compare based on the PK:
var users = from user in UserRepository.FindAll()
select new UserDTO
{
UserId = user.UserId,
Tickets = from ticket in TicketRepository.FindAll()
where ticket.User.UserId == user.UserId
select new TicketDTO
{
TicketId = ticket.TicketId
}
};
(Presuming, here, that the PK of User is called UserId.)

Categories

Resources