LINQ to SQL:如何设置两个表之间的关联以填充字符串列表

时间:2011-04-24 02:54:14

标签: c# linq linq-to-sql associations

我有一个包含两个表的简单数据库:PhotoTag。两个表之间存在一对多(一张照片可以有很多标签)的关系。这是一个图表:

Tables

现在我已经创建了一个Photo类,并使用属性为LINQ-to-SQL设置它。该类的代码如下:

[Table]
public class Photo
{

    [Column(IsDbGenerated = true, IsPrimaryKey = true, CanBeNull = false)]
    public int ID { get; set; }

    [Column(CanBeNull = false)]
    public string Filename { get; set; }

    [Column(CanBeNull = false)]
    public string Description { get; set; }

    [Column(CanBeNull = false)]
    public DateTime DateTaken { get; set; }


    public List<string> Tags { get; set; }

    public override string ToString()
    {
        string result = String.Format("File: {0}, Desc: {1}, Date: {2}, Tags: ", 
            Filename, Description, DateTaken);
        if (Tags != null)
            foreach (string tag in Tags)
                result += tag + ", ";
        return result;
    }
}

您会注意到目前我没有Tags列表的任何属性。我希望能够为Tags列表设置属性(关联),以便为Name表中的Tag字段填充Tag中的所有条目特定PhotoID的表。如果我可以直接执行此操作(即无需设置模仿/关联Tag表的Tag类,则更为可取。由于我只对一个字段(Tag表中的Name)感兴趣而不是很多字段,我认为有办法做到这一点。

这是可能的,如果是这样的话,我将如何使用属性进一步修饰类,以及使用LINQ-to-SQL的simiple Select查询的语法是什么?

如果它有帮助,这里是我用来简单地添加一张新照片然后从数据库中取出所有照片的代码(显然标签信息没有被拉出,因为代码现在已经停止了。)

DataContext context = new DataContext(connectionString);

// add new photo
Photo newPhoto = new Photo { Filename = "MyImage1.jpg", Description = "Me", DateTaken = DateTime.Now };
context.GetTable<Photo>().InsertOnSubmit(newPhoto);
context.SubmitChanges();

// print out all photos
var photoQuery = from m in context.GetTable<Photo>() select m;
foreach (Photo myPhoto in photoQuery)
    textBox1.Text += Environment.NewLine + myPhoto.ToString();

2 个答案:

答案 0 :(得分:1)

您应该参考msdn。上的Attribute Based Mapping文章。

此外,这个article显示了如何使用Association属性修饰EntitySet属性以完成关系建模。

  

如果我可以直接执行此操作(即无需设置模仿/关联Tag表的Tag类),这将是更好的选择。

不可能。 LinqToSql需要知道什么是表或不是表,所以它可以生成正确的sql文本。

您可以做的是制作一组用于表示数据库结构的类型,以及另一组用于程序中其他位置的类型。第二组类型可以有一个表示Photo和Tag数据的类。

使用第一组类型编写查询,然后使用它们构造第二组的实例。

答案 1 :(得分:1)

首先,我建议您使用工具生成实体类(与数据库表对应的类)。我们使用的是sqlmetal,它可以很好地完成工作 接下来,(如果你有一个Tag实体),而不是编写一个为某些照片提取标签的函数:

void GetTags(IEnumerable<Photo> photos)
{
var ids = photos.Select(p=>p.ID).ToList();
var tagsG = (from tag in context.GetTable<Tag>() where ids.Contains(tag.PhotoID) select new {PhotoID, Name}).GroupBy(tag=>tag.PhotoID);
foreach(ph in photos){
ph.Tags = tagsG[ph.ID].Select(tag=>tag.Name).ToList();
}
}

注意,代码可能无法编译我已经在浏览器中编写了它......