15

I am working with a few legacy tables that have relationships, but those relationships haven't been explicitly set as primary/foreign keys. I created a .dbml file using "Linq To Sql Classes" and established the proper Case.CaseID = CaseInfo.CaseID association. My resulting class is CasesDataContext.

My Tables (One to many):

Case
------------------
CaseID (int not null)
MetaColumn1 (varchar)
MetaColumn2 (varchar)
MetaColumn3 (varchar)
...


CaseInfo
------------------
CaseInfoID (int)
CaseID (int nulls allowed)
CaseInfoMeta (varchar)
...

I'm new to LinqToSQL and am having trouble doing..

CasesDataContext db = new CasesDataContext();
var Cases = from c in db.Cases
            where c.CaseInfo.CaseInfoMeta == "some value"
            select c;

(Edit) My problem being that CaseInfo or CaseInfos is not available as a member of Cases.

I heard from a colleague that I might try ADO.Net Entity Data Model to create my Data Context class, but haven't tried that yet and wanted to see if I'd be wasting my time or should I go another route. Any tips, links, help would be most appreciated.

madcolor
  • 8,105
  • 11
  • 51
  • 74
  • did you save the DBML file? i don't think it generates the CS files until you save. Might be why it's not showing CaseInfo as a member. – Darren Kopp Mar 06 '09 at 17:52
  • @madcolor, I posted a sample config in my answer, please check it out as it is probably an issue with the relation config – eglasius Mar 08 '09 at 04:55

7 Answers7

26

Go back to the designer and check the relation is set up correctly. Here is one real life example, with BillStateMasters have "CustomerMasters1" property (customers for the state): alt text

Ps. naming is being cleaned up ...

Update 1: You also need to make sure both tables have a primary defined. If the primary key isn't defined on the database (and can't be defined for whatever reason), make sure to define them in the designer. Open the column's properties, and set it as primary key. That said, entity tracking also won't work if you haven't a primary key for the entity, which for deletes means it silently doesn't updates the entity. So, make sure to review all entities and to have them all with a primary key (as I said, if it can't be on the db, then on the designer).

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
eglasius
  • 35,831
  • 5
  • 65
  • 110
  • 3
    Freddy has the solution.. The only Caveat being that you'll get a "Incorrect AutoSync specification for member error" if your Primary Key is also a Identity field. You may have to shut off Auto-Sync for that column in the designer. – madcolor Mar 16 '09 at 17:34
  • 1
    Not having a primary key tripped me up to! Thanks for the help – Stephen Edmonds Apr 07 '10 at 13:57
  • 2
    +1 for primary keys from me too. I've been banging my head against the wall for almost an hour. Thanks! – Nick Oct 28 '11 at 01:52
5
CasesDataContext db = new CasesDataContext();
var Cases = from c in db.Cases
            join ci in db.CaseInfo on
            ci.ID equals c.InfoID
            where ci.CaseInfoMeta == "some value"
            select new {CASE=c, INFO=ci};

my "join" linq is a bit rusty, but the above should get close to what you're after.

Andrew Theken
  • 3,392
  • 1
  • 31
  • 54
0

Is the association set to One to One or One to Many? If you have the association set to One to Many, then what you have is an EntitySet, not an EntityRef and you'll need to use a where clause on the dependent set to get the correct value. I suspect that you want a One to One relationship, which is not the default. Try changing it to One to One and see if you can construct the query.

Note: I'm just guessing because you haven't actually told us what the "trouble" actually is.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
0

Your query looks correct and should return a query result set of Case objects.

So... what's the problem?

(Edit) My problem being that CaseInfo is not available under Cases... i.e. c.CaseInfo doesn't exist where I'm assuming it would be if there were explicit primary/foreign key relationships.

What do you mean by "not available"? If you created the association in the designer as you say you did, then the query should generate SQL something along the lines of

SELECT [columns] 
FROM Case INNER JOIN CaseInfo 
   ON Case.CaseID = CaseInfo.CaseID
WHERE CaseInfo.CaseInfoMeta = 'some value'

Have you debugged your linq query to get the SQL generated yet? What does it return?

Randolpho
  • 55,384
  • 17
  • 145
  • 179
  • sorry about that.. new to linq. CaseInfo isn't showing up as a member of Cases. – madcolor Mar 06 '09 at 15:51
  • Did you create the association in the designer? Is there a CaseInfos property? – Randolpho Mar 06 '09 at 15:57
  • I did create the association (parent class = cases, child class = CaseInfo) on CaseID. There is no CaseInfo member showing up under Cases. – madcolor Mar 06 '09 at 16:03
  • Is it many-to-many? I think it'd be CaseInfos. If it's not showing up... the only thing I can suggest is maybe rebuilding the project? – Randolpho Mar 06 '09 at 16:14
0

Couple of things you might want to try:

Check the properties of the association. Make sure that the Parent property was created as Public. It does this by default, but something may have changed.

Since you're not getting CaseInfo on C, try typing it the other direction to see if you get ci.Case with intellisense.

Delete and recreate the association all together.

There's something very basic going wrong if the child members are not showing up. It might be best to delete the dbml and recreate the whole thing.

If all else fails, switch to NHibernate. :)

Jeff Schumacher
  • 3,126
  • 3
  • 23
  • 23
0

Is this c#? I think you need == instead of = on this line:

where c.CaseInfo.CaseInfoMeta = "some value"

should read

where c.CaseInfo.CaseInfoMeta == "some value"
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
0

After a few tests, I'm pretty sure the FK relationships are required in the DB regardless of whatever associations are created in Linq-to-SQL. i.e. if you don't have them explicitly set in the DB, then you will have to do a join manually.

madcolor
  • 8,105
  • 11
  • 51
  • 74
  • Updated my answer, you can define then in the designer but you need to make sure both tables have a primary key (which can also be done in the designer - if can't be on the db for some strange reason). – eglasius Mar 15 '09 at 06:46
  • You can define Primary Keys in the designer, but if they don't exist on the tables in the DB, you will get a "Incorrect AutoSync specification for member error". Therefor, Freddy's comment above is a bit misleading. – madcolor Mar 16 '09 at 16:56
  • UPDATE: In the L2SQL designer, I set both columns as Primary keys in both tables (CaseID) and turned off "auto-sync" for the CaseID column on the Case and all is working.. Thanks Freddy. – madcolor Mar 16 '09 at 17:09
  • Also.. I believe that the "Incorrect AutoSync specification for member" error is related to having an identity column solely and not a product of having primary/foreign keys established. – madcolor Mar 16 '09 at 17:31