当对象有关系时,使用LINQ to SQL来添加记录是否有秘密?

问题描述:

我在LINQ to SQL,ASP.NET MVC和C#中工作。我有一个名为genesisRepository的存储库连接到数据库。当对象有关系时,使用LINQ to SQL来添加记录是否有秘密?

我在一个名为Stream的对象中有一个表。它的定义是这样的:

[Table] 
public class Stream 
{ 
    [HiddenInput(DisplayValue = false)] 
    [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
    public long StreamID { get; set; } 

    [Required(ErrorMessage = "Please enter a stream name")] 
    [Column] 
    public string StreamName { get; set; } 

    /* Other columns removed for brevity */ 

    [Required(ErrorMessage = "Please enter a stream URL")] 
    [Column] 
    public string StreamUrl { get; set; } 

    private EntitySet<StreamEntry> _StreamEntry; 
    [System.Data.Linq.Mapping.Association(Storage = "_StreamEntry", OtherKey = "StreamID")] 
    public EntitySet<StreamEntry> StreamEntry 
    { 
     get { return this._StreamEntry; } 
     set { this._StreamEntry.Assign(value); } 
    } 

    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes; 
    [System.Data.Linq.Mapping.Association(Storage = "_Stream2FieldTypes", OtherKey = "StreamID")] 
    public EntitySet<Stream2FieldTypes> Stream2FieldTypes 
    { 
     get { return this._Stream2FieldTypes; } 
     set { this._Stream2FieldTypes.Assign(value); } 
    } 

} 

我有我的Stream表中创建新记录在我的控制器的测试动作。

public ActionResult StreamTest() 
    { 
     // create new stream 
     var stream = new Genesis.Domain.Entities.Stream(); 

     stream.StreamUrl = "url"; 
     stream.StreamName = "name"; 
     stream.StreamBody = null; 
     stream.StreamTitle = null; 
     stream.StreamKeywords = null; 
     stream.StreamDescription = null; 

     genesisRepository.CreateStream(stream); 

     return View("Index"); 
    } 

功能genesisRepository()看起来是这样的:

public long CreateStream(Stream stream) 
    {    
     streamTable.InsertOnSubmit(stream); 
     streamTable.Context.SubmitChanges(); 
     return stream.StreamID; 
    } 

我得到一个空引用错误,当我执行的ActionResult StreamTest()。 genesisRepository不为空。 streamTable不为空,并且新创建的对象stream也显然不为空。我能想到的唯一的东西是空的EntitySet<T>属性定义的外国关系。

所以,我修改了代码的ActionResult是这样的:

public ActionResult StreamTest() 
    { 
     // create new stream 
     var stream = new Genesis.Domain.Entities.Stream(); 

     stream.Stream2FieldTypes = new EntitySet<Stream2FieldTypes>(); // new 
     stream.StreamEntry = new EntitySet<StreamEntry>(); // new 
     stream.StreamUrl = "url"; 
     stream.StreamName = "name"; 
     stream.StreamBody = null; 
     stream.StreamTitle = null; 
     stream.StreamKeywords = null; 
     stream.StreamDescription = null; 

     genesisRepository.CreateStream(stream); // CreateStream() returns ID as long 

     return View("Index"); 
    } 

但是,当我尝试了,我得到这个错误:

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object. 
Source Error: 
Line 58:   { 
Line 59:    get { return this._Stream2FieldTypes; } 
Line 60:    set { this._Stream2FieldTypes.Assign(value); } <-- the offending line 
Line 61:   } 
Line 62: 
Source File: C:\path\to\Stream.cs Line: 60 

我可以创建一个使用streamTable.Context.ExecuteCommand("INSERT INTO genesis.dbo.Stream (StreamName, StreamUrl) VALUES ('Name', 'url');");的新纪录。

我不明白如何从这里前进。我如何简单地创建Stream的新纪录?

+1

@quakkels,你应该* *强烈不考虑自己手工编码的实体类。 LinqToSql在这个部门设计得非常糟糕(当你的实体类设置不正确时,例外情况非常糟糕),并且长远来看,你将来会在未来看到一个受到伤害的世界。 – 2010-10-06 20:03:36

+0

@Kirk Woll - 是的......似乎是这样。我使用这种方法的原因是因为我一直在阅读Steven Sanderson的书Pro ASP.NET MVC 2 Framework,他的所有示例都是手动编码的。我没有任何其他方式的知识。 – quakkels 2010-10-06 20:10:18

+0

@quakkels,当然,但sqlmetal.exe非常易于使用,尽管您必须跳过一些环节才能继续在您的linq-to-sql类上使用数据注释验证。 – 2010-10-06 20:16:50

请尝试以下操作。在你的类声明替换此:

public class Stream 
{ 
    private EntitySet<StreamEntry> _StreamEntry; 
    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes; 
} 

与此:

public class Stream 
{ 
    private EntitySet<StreamEntry> _StreamEntry = new EntitySet<StreamEntry>(); 
    private EntitySet<Stream2FieldTypes> _Stream2FieldTypes = new EntitySet<Stream2FieldTypes>(); 
} 
+0

哇......不行! – quakkels 2010-10-06 20:35:09

+0

是的!!!!!!!!!!!万分感谢! – quakkels 2010-10-06 20:36:32

+0

令人惊叹!自从星期一以来我一直在想这个问题! – quakkels 2010-10-06 20:37:10