MongoDB 和派生类

我在使用 MongoDB 保存特定类时遇到问题。

我的抽象类如下:

public abstract class Enumeration : IComparable
{
public string Name { get; }
public int Id { get; }

protected Enumeration(int id, string name)
{
  Id = id;
  Name = name;
}

public override string ToString() => Name;

public static IEnumerable<T> GetAll<T>() where T : Enumeration
{
  var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

  return fields.Select(f => f.GetValue(null)).Cast<T>();
}

public override bool Equals(object obj)
{
  var otherValue = obj as Enumeration;

  if (otherValue == null)
    return false;

  var typeMatches = GetType().Equals(obj.GetType());
  var valueMatches = Id.Equals(otherValue.Id);

  return typeMatches && valueMatches;
}

public override int GetHashCode() => Id.GetHashCode();

public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
{
  var absoluteDifference = Math.Abs(firstValue.Id - secondValue.Id);
  return absoluteDifference;
}

public static T FromValue<T>(int value) where T : Enumeration
{
  var matchingItem = Parse<T, int>(value, "value", item => item.Id == value);
  return matchingItem;
}

public static T FromDisplayName<T>(string displayName) where T : Enumeration
{
  var matchingItem = Parse<T, string>(displayName, "display name", item => item.Name == displayName);
  return matchingItem;
}

private static T Parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration
{
  var matchingItem = GetAll<T>().FirstOrDefault(predicate);

  if (matchingItem == null)
    throw new InvalidOperationException($"'{value}' is not a valid {description} in {typeof(T)}");

  return matchingItem;
}

public int CompareTo(object other) => Id.CompareTo(((Enumeration)other).Id);
}

派生类:

public class SeatState : Enumeration
{
public static SeatState Free = new SeatState(1, nameof(Free).ToLowerInvariant());
public static SeatState Booked = new SeatState(2, nameof(Booked).ToLowerInvariant());
public static SeatState Reserved = new SeatState(3, nameof(Reserved).ToLowerInvariant());

public static IEnumerable<SeatState> List() => new[] { Free, Booked, Reserved };

public SeatState(int id, string name)
  : base(id, name)
{
}

public static SeatState FromName(string name)
{
  var state = List().SingleOrDefault(s => string.Equals(s.Name, name, StringComparison.CurrentCultureIgnoreCase));

  if (state == null)
    throw new Exception($"Possible values for SeatState: {string.Join(",", List().Select(s => s.Name))}");

  return state;
}

public static SeatState From(int id)
{
  var state = List().SingleOrDefault(s => s.Id == id);

  if (state == null)
    throw new Exception($"Possible values for SeatState: {string.Join(",", List().Select(s => s.Name))}");

  return state;
}
}

当我尝试保存具有SeatState属性的类时,mongo 抛出此错误:

System.ArgumentOutOfRangeException:memberInfo 参数必须用于类 SeatState,但用于类 Enumeration。

我也尝试过BsonClassMap.RegisterClassMap<Enumeration>()(有和没有IsRootClass),BsonClassMap.RegisterClassMap<SeatState>()但没有成功。似乎问题出在静态属性上,但我需要它们。

非常感谢对我做错了什么的任何澄清。

对于可能有同样问题的其他人,解决方案如下:

BsonClassMap.RegisterClassMap<Enumeration>(cm =>
{
  cm.SetIsRootClass(true);
  cm.MapMember(m => m.Id);
  cm.MapMember(m => m.Name);
});
BsonClassMap.RegisterClassMap<SeatState>(cm =>
{
  cm.MapCreator(c => new SeatState(c.Id, c.Name));
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章