views:

1020

answers:

1

I am using VB.NET with LINQ to MS SQL. I have two following tables. Now I want to insert multiple items in Tags Table using LINQ, but also wants to check that if any of tag exists in Tags table. It doesn't insert it again and bring the TagID in both cases (if inserted or if found existed)

CREATE TABLE Tags
    (TagID bigint not null , 
    Tag varchar(100) NULL )

CREATE TABLE VideoTags
    (VideoID bigint not null , 
    TagID bigint not null )

What's the best way to acheive this using LINQ?

Thanks in advance

+4  A: 

LINQ is a query technology, but I think we know what you mean; you might want to be a bit more specific whether this is LINQ-to-SQL or Entity Framework. You might also want to clarify what "bulk" means in your case... for 10-100 records you might use a different answer to 10,000 records (where SqlBulkCopy into a staging table and a stored procedure to import at the db would be the best idea).

For a relatively low number - just use your ORM tool to find the records - for example with LINQ-to-SQL (perhaps with a spanning serializable transaction) - and using C# for illustration (updated to show loop and cache):

Dictionary<string,Tag> knownTags = new Dictionary<string,Tag>();
foreach(... your data ...) {
    Tag tag;
    if(!knownTags.TryGetValue(tagName, out tag)) {
        tag = ctx.Tags.SingleOrDefault(t => t.Name == tagName);
        if(tag == null) {
            tag = new Tag { Name = tagName };
            ctx.Tags.InsertOnSubmit(tag);
        }
        knownTags.Add(tagName, tag);
    }
    // insert video tag
}
ctx.SubmitChanges();

Actually, for performance reasons I wonder whether this might be one of those occasions where a natural-key makes sense - i.e. use Tag (the varchar) as the primary key, and duplicate it (as a foreign key) in VideoTags - then you don't need to join to the Tags table all the time.


If the numbers are larger, it is pretty easy to use SqlBulkCopy; just put the data into a DataTable and push it over, then do the work in TSQL.

Marc Gravell
I am using LINQ-TO-SQL and I want to insert 10-20 records at a time. The above query insert one value at a time. Can I insert all 10-20 values in one go and still retreive the TagID
Marc V
You can use as many `InsertOnSubmit` as you need. The TagID won't be available until you call `SubmitChanges`, but you don't actually need it - you should be able to give the `VideoTag` objects the appropriate `tag` object. Of course, with a natural key this is a non-issue.
Marc Gravell
Note additionally that you may want to cache the known tags in local Dictionary<string,Tag> - otherwise you may do some unnecessary SQL queries. I'll update...
Marc Gravell