如何通过引用而不是按值使用List <model>?</model>

时间:2013-05-26 22:10:47

标签: c# list model-binding

行。我有拥有List的州。我希望有多个State实例使用相同的Series列表。

public class State
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Series> Serieses { get; set; }
}

public class Series
{
    public int Id { get; set; }
    public string Name { get; set; }
}

通过键入状态名称并从ListBox中选择一个或多个系列来创建状态后:

public ActionResult Create(State state, FormCollection form)
    {

      // method to get selected Series from db

      foreach (var sItem in seriesModel//List of Possible Series)
      {
          foreach (var item in Selections//User selected Series)
          {

             if (sItem.Name == item.Name)
             {
                newSeries.Add(sItem);
             }
          }
      }

      state.Serieses = newSeries;
      _db.Entry(state).State = EntityState.Modified;
      _db.SaveChanges();

问题出在我用List创建一个State实例之后。如果我创建第二个实例并在其列表中使用相同的Series,则第一个将在其列表中丢失该Series。所以很明显,系列是通过价值而不是参考传递的。我是C#的新手,但回到C ++,我们会使用指针。这样,如果我更改Series的原始值,它将显示在指向它的每个State列表中。我还注意到在数据库的表数据中,它为每个系列添加了一个外键State_Id。这是我使用Code First方法时创建的表定义。

CREATE TABLE [dbo].[Series] (
[Id]       INT            IDENTITY (1, 1) NOT NULL,
[Name]     NVARCHAR (MAX) NULL,
[State_Id] INT            NULL,
CONSTRAINT [PK_dbo.Series] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.Series_dbo.States_State_Id] FOREIGN KEY ([State_Id]) REFERENCES [dbo].[States] ([Id])

5 个答案:

答案 0 :(得分:0)

引用here时,“ ref 关键字会导致参数通过引用传递,而不是按值传递。”

使用此方法的一种丑陋方式如下所示,因为您无法更改value的声明:

public MyClass {
    private string myString;

    public void SetMyString(ref string str) {
        myString = str
    }
}

我不是真的建议这个。

答案 1 :(得分:0)

如何让它静止?

public static ICollection<Series> Serieses { get; set; }

答案 2 :(得分:0)

如果您不想以不同方式更改每个实例的列表,请使用静态列表。您可以像这样访问它。

State.Serieses

答案 3 :(得分:0)

使用AddRange()方法

//replace 'state.Serieses = newSeries;' with
state.Serieses.AddRange(newSeries);

在状态构造函数中确保使用新的空系列初始化Serieses

BTW Serieses不是单词。 系列的复数是系列

<强>更新

我不知道为什么你需要集合的接口,不能只使用List<Series>。该部分尚未解释。为什么virtual

以下是有关如何保留相同集合并使用AddRange()

的框架代码
// StackOverflow 16764155
public class Series
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class State
{
    public State()
    {
        Serieses = new List<Series>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Series> Serieses { get; set; }
}

public class DbForm
{
    public IEnumerable<Series> Selection { get; }
}

public class DbLogic
{

    public void Create(State state, IEnumerable<Series> selection)
    {
        state.Serieses.AddRange(selection);

        // do db stuff
        // _db.Entry(state).State = EntityState.Modified;
        // _db.SaveChanges();
    }
}


class Program
{
    static void Main(string[] args)
    {
        var form = new DbForm();
        var state = new State();
        var db = new DbLogic();
        // stuff here
        var sel = form.Selection;
        db.Create(state, sel);
    }
}

答案 4 :(得分:0)

将Entity Framework与Code First一起使用,您还必须在系列中添加一组State,以生成多对多关系表。

public class Series
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<State> States { get; set; } 
}

您还必须使用包管理器控制台运行代码优先数据迁移。

Add-Migration <YourMigrationNameHere>

下次运行您的应用后会导致以下数据库结构:

enter image description here