在查询中比较sql和c#列表?

vuktfyat  于 2021-08-09  发布在  Java
关注(0)|答案(4)|浏览(406)

我在比较sql数据库中的值和代码中的对象列表时遇到问题。
对象在数据库中不存在
列表中的对象示例:

{
    public long CompareId
    public bool HasAccess
}

我在c#中使用sqlbuilder,然后我想进行如下查询:
编造代码

SELECT * FROM EntityPermission
WHERE EntityPermission.HasAccess = listOfObjects.Where(obj => obj.CompareId == EntityPermission.CompareId).HasAccess

在更复杂的代码中,但使用sql builder

query.WHERE("(EntityPermission.HasAccess = {0})", listOfObjects.Where(obj => obj.CompareId == EntityPermission.CompareId).HasAccess)

我很清楚我在这里混合了c#和sql,但这是解释我想要实现什么的最好方法。
用词
我想找到一个entitypermission,其中hasaccess列等于具有相同id的对象的hasaccess属性。
非常感谢大家的帮助!

gc0ot86w

gc0ot86w1#

您要查找的是sql where…in()语法。
如果您使用的是生成sql的工具,则需要执行以下操作:
1) 获取要比较的值的列表
2) 从它们中创建如下字符串:

"('value1','value2','value3')"

3) 然后生成如下所示的查询:

SELECT * FROM EntityPermission
WHERE EntityPermission.HasAccess
IN ('value1','value2','value3')

对于类似orm的实体框架、nhibernate等,可以执行以下操作:

var results = db.EntityPermissions
                .Where(x => listOfObjects
                           .Where(obj => obj.CompareId == EntityPermission.CompareId)
                .Select(y => y.HasAccess)
                .Contains(x.HasAccess))
yuvru6vn

yuvru6vn2#

可以使用表值参数和用户定义的类型,然后使用内部联接:

SELECT * FROM EntityPermission ep
INNER JOIN @foo f ON f.Id = ep.Id AND f.HasAccess = ep.HasAccess

然而:UDT和TVP确实很难使用;坦白地说,我很想创建两个串联的字符串:

string with = string.Join(",", list.Where(x => x.HasAccess).Select(x => x.Id));
string without = string.Join(",", list.Where(x => !x.HasAccess).Select(x => x.Id));

并将其作为参数传递给 string_split :

SELECT *
FROM EntityPermission
WHERE (Id in (select value from string_split(@with, ',')) and HasAccess = 1)
OR (Id in (select value from string_split(@without, ',')) and HasAccess = 0)
tyg4sfes

tyg4sfes3#

您可以首先在结果表中获取sql查询,然后使用linq获取所需的值。我知道这不是最有效的方法,但它可以工作。

public virtual List<YOUR_DTO> ExampleOperation(YOUR_DTO dto)
        {

            sqlText="SELECT * FROM EntityPermission ";
            dbComm = db.GetSqlStringCommand(sqlText);

            DataTable table = this.Database.ExecuteDataSet(dbComm).Tables[0];

            List<YOUR_DTO> result = new List<YOUR_DTO>();
            foreach (DataRow row in table.Rows)
            {
                result.Add(new YOUR_DTO()
                {
                    ...
                });
            }
            //LINQ
            result = result.Where(obj => obj.CompareId == EntityPermission.CompareId).HasAccess;
            return result;
        }
b4lqfgs4

b4lqfgs44#

我想找到一个entitypermission,其中hasaccess列等于具有相同id的对象的hasaccess属性。
你有table吗 EntityPermissions . 每 EntityPermission 此表中至少有一个布尔属性 HasAccess ,以及long属性中的主键 Id 此外,您还有一个对象列表,其中每个对象至少有一个compareid和一个hasaccess。
如果我正确地阅读了您的需求,那么您需要所有的entitypermissions,其id也是列表中的compareid,并且具有相等的hasaccess值。
因此,如果列表中有值:

{10, false}, {11, true}, {12, false},

你有全部权限:

Id  HasAccess 
09  true         don't want this one, Id is not in the list
10  true         don't want this one, Id is in the list, but HasAccess incorrect
11  true         I want this one: Id is in the list, HasAccess is correct
12  false        I want this one: Id is in the list, HasAccess is correct

通常你会用 Where(x => y.Contains(x)) 为了这个。问题是,使用此选项只能选择一个属性。

var checkValues = new
{
    new {CompareId = 10, HasAccess = false},
    new {CompareId = 11, HasAccess = true},
    new {CompareId = 12, HasAccess = false},
}

var result = dbContext.EntityPermissions.Select(entityPermission => new
{
    ValueToCompare = new
    {
         CompareId = entityPermission.Id,
         HasAccess = entityPermission.HasAccess,
    },

    Original = entityPermission,
})

// keep only those selected items that have a ValueToCompare in CheckValues
.Where(selectedItem => checkValues.Contains(selectedItem.ValueToCompare)

// from the remaining items, extract the original EntityPermission
.Select(selectedItem => selectedItem.Original);

相关问题