C# LINQ到SQL可选列

C# LINQ到SQL可选列,c#,performance,linq-to-sql,stored-procedures,C#,Performance,Linq To Sql,Stored Procedures,我需要一个在LINQ到SQL定义中具有可选列的功能。因此LINQtoSQL通常会忽略selects和updates等中的此列。 但如果select包含此列的值,则应使用此值 长版本: 情景 我有以下表格: 如果Field.fieldview.Count()大于0,则此字段应可见 问题 如果我检查上述可见性,请执行以下操作: Field.FieldViews.Count() 然后针对每个字段对数据库进行一次查询。 所以在我的项目中,有时高达1000倍 我的解决方案 我编写了一个存储过程: S

我需要一个在LINQ到SQL定义中具有可选列的功能。因此LINQtoSQL通常会忽略selects和updates等中的此列。 但如果select包含此列的值,则应使用此值

长版本:

情景 我有以下表格:

如果Field.fieldview.Count()大于0,则此字段应可见

问题 如果我检查上述可见性,请执行以下操作:

Field.FieldViews.Count()
然后针对每个字段对数据库进行一次查询。 所以在我的项目中,有时高达1000倍

我的解决方案 我编写了一个存储过程:

 SELECT
   f.*,
   (SELECT COUNT(*) FROM [fieldViews] v WHERE v.fieldId = f.fieldId) AS Visible
  FROM [fields] f
  WHERE
   f.X BETWEEN @xFrom AND @xTo AND
   f.Y BETWEEN @yFrom AND @yTo
from d in DataContext.Fields select d;
为了使用此附加列,我添加了以下代码:

 public partial class Field
  {
   private bool visible = false;
 
   [Column(Storage = "Visible", DbType = "INT")]
   public bool Visible
   {
    get
    {
     return visible;
    }
    set
    {
     visible = value;
    }
   }
  }
这很好用。

但是

问题 如果我从字段表中提取条目而不使用存储过程:

 SELECT
   f.*,
   (SELECT COUNT(*) FROM [fieldViews] v WHERE v.fieldId = f.fieldId) AS Visible
  FROM [fields] f
  WHERE
   f.X BETWEEN @xFrom AND @xTo AND
   f.Y BETWEEN @yFrom AND @yTo
from d in DataContext.Fields select d;
我得到了以下错误:

错误的存储属性:“在成员”模型上可见。字段。可见。

因此,我在数据库表中添加了“可见”列:

ALTER TABLE dbo.Fields ADD
 Visible int NOT NULL CONSTRAINT DF_Fields_Visible DEFAULT 0
这样我就可以解决上面提到的错误。

但是

下一个问题 我使用存储过程获取了一些字段对象。 现在我对其中一些对象进行了一些更改。 如果我现在尝试提交这些更改,它将不起作用。查看生成的查询可以揭示原因:

 UPDATE [dbo].[Fields]
 SET [X] = @p3
 WHERE ([FieldId] = @p0) AND ([X] = @p1) AND ([Y] = @p2) AND ([Visible] = 3)
这里的问题是,它在where语句中使用了“Visible”列。但“可见”列始终为0。 如果使用存储过程获取数据,则Visible仅大于0

我需要什么 类似于ColumnAttribute,其中不需要列


更新时从where语句中删除列的方法。

我们通过查询详细信息表解决了原始问题,类似于:

FieldViewsRepository.FieldViews.Where(fv => fv.FieldViewId == Field.FieldID).Count()
这只生成对数据库的一个查询

如果需要具有附加可见属性的对象列表,可以执行以下操作:

FieldRepository.Fields.Select(f => new { ID=f.FieldID, X=f.X, y=f.Y, Visible=f.FieldViews.Any() }


与Visible是field对象上的一个属性并对每个字段执行查询的情况不同,在这种情况下,字段和Visible属性在一个查询中从数据库中获取。

无需将其存储为field表上的一列-您可以在field类中计算:

public bool Visible
{
    get { return this.FieldViews.Count() > 0; }
}

我找到了解决我问题的方法:

        private bool visible = false;
    public bool Visible
    {
        get
        {
            return visible;
        }
        set
        {
            visible = value;
        }
    }

    private int fakeVisible
    {
        get
        {
            return 0;
        }
        set
        {
            visible = value > 0;
        }
    }

    [Column(Name="Visible", Storage = "fakeVisible", DbType = "Int NOT NULL")]
    public int FakeVisible { get; set; }

无论如何谢谢你

是的,这会有用的。我也用过这个。。。但正如我所提到的:对于我选中的每个字段,这将生成一个查询。如果我检查1000个字段-它将生成1000次此查询:从[dbo].[FieldView]中选择[t0].[FieldView ID],[t0].[FieldId]作为[t0],其中[t0].[FieldId]=@p0。。。使用存储过程要快得多!?